From nobody Fri Oct 17 10:31:34 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF02FC433FE for ; Wed, 19 Oct 2022 13:52:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230273AbiJSNw3 (ORCPT ); Wed, 19 Oct 2022 09:52:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233702AbiJSNv6 (ORCPT ); Wed, 19 Oct 2022 09:51:58 -0400 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4EDA2189C2C; Wed, 19 Oct 2022 06:35:42 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id 5EB30CE20EC; Wed, 19 Oct 2022 08:45:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2498EC43150; Wed, 19 Oct 2022 08:45:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1666169113; bh=XDjOCPtyJ+ylfAPNVAyr7LIRSuqzjxkX5201IvT0urI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UOKwMBG3c/zSN1lr8jWluF53MKxAD/WgxxSftan4Uu/O2EBygdwj4Lidjq5XlJ1y6 TFOhSmreEG7i+m2MUc45KcM7MccF4TQ6BIloUfkGuq2qepAwMoAuuqlwJHOQT24dM2 th5Xrd/254tF2ssowFTNVD/0QHMnl9nwer94f4zM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andrew Morton , Tom Zanussi , "Masami Hiramatsu (Google)" , "Steven Rostedt (Google)" Subject: [PATCH 6.0 163/862] tracing: Move duplicate code of trace_kprobe/eprobe.c into header Date: Wed, 19 Oct 2022 10:24:10 +0200 Message-Id: <20221019083257.177182803@linuxfoundation.org> X-Mailer: git-send-email 2.38.0 In-Reply-To: <20221019083249.951566199@linuxfoundation.org> References: <20221019083249.951566199@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Steven Rostedt (Google) commit f1d3cbfaafc10464550c6d3a125f4fc802bbaed5 upstream. The functions: fetch_store_strlen_user() fetch_store_strlen() fetch_store_string_user() fetch_store_string() are identical in both trace_kprobe.c and trace_eprobe.c. Move them into a new header file trace_probe_kernel.h to share it. This code will later be used by the synthetic events as well. Marked for stable as a fix for a crash in synthetic events requires it. Link: https://lkml.kernel.org/r/20221012104534.467668078@goodmis.org Cc: stable@vger.kernel.org Cc: Andrew Morton Cc: Tom Zanussi Acked-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Fixes: bd82631d7ccdc ("tracing: Add support for dynamic strings to syntheti= c events") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_eprobe.c | 60 +---------------------- kernel/trace/trace_kprobe.c | 60 +---------------------- kernel/trace/trace_probe_kernel.h | 96 +++++++++++++++++++++++++++++++++= +++++ 3 files changed, 106 insertions(+), 110 deletions(-) create mode 100644 kernel/trace/trace_probe_kernel.h --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -16,6 +16,7 @@ #include "trace_dynevent.h" #include "trace_probe.h" #include "trace_probe_tmpl.h" +#include "trace_probe_kernel.h" =20 #define EPROBE_EVENT_SYSTEM "eprobes" =20 @@ -453,29 +454,14 @@ NOKPROBE_SYMBOL(process_fetch_insn) static nokprobe_inline int fetch_store_strlen_user(unsigned long addr) { - const void __user *uaddr =3D (__force const void __user *)addr; - - return strnlen_user_nofault(uaddr, MAX_STRING_SIZE); + return kern_fetch_store_strlen_user(addr); } =20 /* Return the length of string -- including null terminal byte */ static nokprobe_inline int fetch_store_strlen(unsigned long addr) { - int ret, len =3D 0; - u8 c; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if (addr < TASK_SIZE) - return fetch_store_strlen_user(addr); -#endif - - do { - ret =3D copy_from_kernel_nofault(&c, (u8 *)addr + len, 1); - len++; - } while (c && ret =3D=3D 0 && len < MAX_STRING_SIZE); - - return (ret < 0) ? ret : len; + return kern_fetch_store_strlen(addr); } =20 /* @@ -485,21 +471,7 @@ fetch_store_strlen(unsigned long addr) static nokprobe_inline int fetch_store_string_user(unsigned long addr, void *dest, void *base) { - const void __user *uaddr =3D (__force const void __user *)addr; - int maxlen =3D get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest =3D get_loc_data(dest, base); - - ret =3D strncpy_from_user_nofault(__dest, uaddr, maxlen); - if (ret >=3D 0) - *(u32 *)dest =3D make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string_user(addr, dest, base); } =20 /* @@ -509,29 +481,7 @@ fetch_store_string_user(unsigned long ad static nokprobe_inline int fetch_store_string(unsigned long addr, void *dest, void *base) { - int maxlen =3D get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if ((unsigned long)addr < TASK_SIZE) - return fetch_store_string_user(addr, dest, base); -#endif - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest =3D get_loc_data(dest, base); - - /* - * Try to get string again, since the string can be changed while - * probing. - */ - ret =3D strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen); - if (ret >=3D 0) - *(u32 *)dest =3D make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string(addr, dest, base); } =20 static nokprobe_inline int --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -20,6 +20,7 @@ #include "trace_kprobe_selftest.h" #include "trace_probe.h" #include "trace_probe_tmpl.h" +#include "trace_probe_kernel.h" =20 #define KPROBE_EVENT_SYSTEM "kprobes" #define KRETPROBE_MAXACTIVE_MAX 4096 @@ -1223,29 +1224,14 @@ static const struct file_operations kpro static nokprobe_inline int fetch_store_strlen_user(unsigned long addr) { - const void __user *uaddr =3D (__force const void __user *)addr; - - return strnlen_user_nofault(uaddr, MAX_STRING_SIZE); + return kern_fetch_store_strlen_user(addr); } =20 /* Return the length of string -- including null terminal byte */ static nokprobe_inline int fetch_store_strlen(unsigned long addr) { - int ret, len =3D 0; - u8 c; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if (addr < TASK_SIZE) - return fetch_store_strlen_user(addr); -#endif - - do { - ret =3D copy_from_kernel_nofault(&c, (u8 *)addr + len, 1); - len++; - } while (c && ret =3D=3D 0 && len < MAX_STRING_SIZE); - - return (ret < 0) ? ret : len; + return kern_fetch_store_strlen(addr); } =20 /* @@ -1255,21 +1241,7 @@ fetch_store_strlen(unsigned long addr) static nokprobe_inline int fetch_store_string_user(unsigned long addr, void *dest, void *base) { - const void __user *uaddr =3D (__force const void __user *)addr; - int maxlen =3D get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest =3D get_loc_data(dest, base); - - ret =3D strncpy_from_user_nofault(__dest, uaddr, maxlen); - if (ret >=3D 0) - *(u32 *)dest =3D make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string_user(addr, dest, base); } =20 /* @@ -1279,29 +1251,7 @@ fetch_store_string_user(unsigned long ad static nokprobe_inline int fetch_store_string(unsigned long addr, void *dest, void *base) { - int maxlen =3D get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if ((unsigned long)addr < TASK_SIZE) - return fetch_store_string_user(addr, dest, base); -#endif - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest =3D get_loc_data(dest, base); - - /* - * Try to get string again, since the string can be changed while - * probing. - */ - ret =3D strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen); - if (ret >=3D 0) - *(u32 *)dest =3D make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string(addr, dest, base); } =20 static nokprobe_inline int --- /dev/null +++ b/kernel/trace/trace_probe_kernel.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __TRACE_PROBE_KERNEL_H_ +#define __TRACE_PROBE_KERNEL_H_ + +/* + * This depends on trace_probe.h, but can not include it due to + * the way trace_probe_tmpl.h is used by trace_kprobe.c and trace_eprobe.c. + * Which means that any other user must include trace_probe.h before inclu= ding + * this file. + */ +/* Return the length of string -- including null terminal byte */ +static nokprobe_inline int +kern_fetch_store_strlen_user(unsigned long addr) +{ + const void __user *uaddr =3D (__force const void __user *)addr; + + return strnlen_user_nofault(uaddr, MAX_STRING_SIZE); +} + +/* Return the length of string -- including null terminal byte */ +static nokprobe_inline int +kern_fetch_store_strlen(unsigned long addr) +{ + int ret, len =3D 0; + u8 c; + +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if (addr < TASK_SIZE) + return kern_fetch_store_strlen_user(addr); +#endif + + do { + ret =3D copy_from_kernel_nofault(&c, (u8 *)addr + len, 1); + len++; + } while (c && ret =3D=3D 0 && len < MAX_STRING_SIZE); + + return (ret < 0) ? ret : len; +} + +/* + * Fetch a null-terminated string from user. Caller MUST set *(u32 *)buf + * with max length and relative data location. + */ +static nokprobe_inline int +kern_fetch_store_string_user(unsigned long addr, void *dest, void *base) +{ + const void __user *uaddr =3D (__force const void __user *)addr; + int maxlen =3D get_loc_len(*(u32 *)dest); + void *__dest; + long ret; + + if (unlikely(!maxlen)) + return -ENOMEM; + + __dest =3D get_loc_data(dest, base); + + ret =3D strncpy_from_user_nofault(__dest, uaddr, maxlen); + if (ret >=3D 0) + *(u32 *)dest =3D make_data_loc(ret, __dest - base); + + return ret; +} + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max + * length and relative data location. + */ +static nokprobe_inline int +kern_fetch_store_string(unsigned long addr, void *dest, void *base) +{ + int maxlen =3D get_loc_len(*(u32 *)dest); + void *__dest; + long ret; + +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if ((unsigned long)addr < TASK_SIZE) + return kern_fetch_store_string_user(addr, dest, base); +#endif + + if (unlikely(!maxlen)) + return -ENOMEM; + + __dest =3D get_loc_data(dest, base); + + /* + * Try to get string again, since the string can be changed while + * probing. + */ + ret =3D strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen); + if (ret >=3D 0) + *(u32 *)dest =3D make_data_loc(ret, __dest - base); + + return ret; +} + +#endif /* __TRACE_PROBE_KERNEL_H_ */