linux-modules.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] tracing: Fix multiple issues in trace_printk module handling
@ 2025-09-06 13:41 Fidal Palamparambil
  2025-09-07  1:23 ` Luis Chamberlain
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Fidal Palamparambil @ 2025-09-06 13:41 UTC (permalink / raw)
  To: linux-modules
  Cc: mcgrof, petr.pavlu, da.gomez, samitolvanen, linux-kernel,
	Fidal palamparambil

From: Fidal palamparambil <rootuserhere@gmail.com>

This commit addresses several bugs and potential issues in the
trace_printk module format handling code:

1. Memory leak fix: In hold_module_trace_bprintk_format(), ensure
   proper cleanup when format string allocation fails by setting
   tb_fmt to NULL after freeing it.

2. NULL pointer dereference prevention: Added NULL checks in
   t_show() function before dereferencing format pointers.

3. Input validation: Added NULL check in trace_is_tracepoint_string()
   to prevent potential NULL pointer dereference.

4. Type safety: Fixed type casting in t_show() to use proper
   unsigned long casting for pointer arithmetic.

5. Error handling: Improved error checking in
   init_trace_printk_function_export() by using IS_ERR() to check
   dentry pointer.

6. Code robustness: Added additional pointer validation throughout
   the code to handle potential edge cases.

7. Memory safety: Ensured consistent handling of format pointers
   when memory allocation failures occur.

These fixes improve the stability and reliability of the trace_printk
infrastructure, particularly when dealing with module loading/unloading
and format string management.

Signed-off-by: Fidal palamparambil <rootuserhere@gmail.com>
---
 kernel/trace/trace_printk.c      |  33 +--
 kernel/trace/trace_printk.c.orig | 400 +++++++++++++++++++++++++++++++
 2 files changed, 419 insertions(+), 14 deletions(-)
 create mode 100644 kernel/trace/trace_printk.c.orig

diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 29f6e95439b6..cb962c6c02f8 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -76,10 +76,12 @@ void hold_module_trace_bprintk_format(const char **start, const char **end)
 				list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
 				strcpy(fmt, *iter);
 				tb_fmt->fmt = fmt;
-			} else
+			} else {
 				kfree(tb_fmt);
+				tb_fmt = NULL;
+			}
 		}
-		*iter = fmt;
+		*iter = tb_fmt ? tb_fmt->fmt : NULL;
 
 	}
 	mutex_unlock(&btrace_mutex);
@@ -253,7 +255,10 @@ EXPORT_SYMBOL_GPL(__ftrace_vprintk);
 
 bool trace_is_tracepoint_string(const char *str)
 {
-	const char **ptr = __start___tracepoint_str;
+	const char **ptr;
+
+	if (!str)
+		return false;
 
 	for (ptr = __start___tracepoint_str; ptr < __stop___tracepoint_str; ptr++) {
 		if (str == *ptr)
@@ -311,19 +316,19 @@ static void *t_next(struct seq_file *m, void * v, loff_t *pos)
 static int t_show(struct seq_file *m, void *v)
 {
 	const char **fmt = v;
-	const char *str = *fmt;
-	int i;
+	const char *str;
 
-	if (!*fmt)
+	if (!fmt || !*fmt)
 		return 0;
 
-	seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
+	str = *fmt;
+	seq_printf(m, "0x%lx : \"", (unsigned long)fmt);
 
 	/*
 	 * Tabs and new lines need to be converted.
 	 */
-	for (i = 0; str[i]; i++) {
-		switch (str[i]) {
+	for (; *str; str++) {
+		switch (*str) {
 		case '\n':
 			seq_puts(m, "\\n");
 			break;
@@ -337,7 +342,7 @@ static int t_show(struct seq_file *m, void *v)
 			seq_puts(m, "\\\"");
 			break;
 		default:
-			seq_putc(m, str[i]);
+			seq_putc(m, *str);
 		}
 	}
 	seq_puts(m, "\"\n");
@@ -378,10 +383,10 @@ static const struct file_operations ftrace_formats_fops = {
 
 static __init int init_trace_printk_function_export(void)
 {
-	int ret;
+	struct dentry *dentry;
 
-	ret = tracing_init_dentry();
-	if (ret)
+	dentry = tracing_init_dentry();
+	if (IS_ERR(dentry))
 		return 0;
 
 	trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
@@ -397,4 +402,4 @@ static __init int init_trace_printk(void)
 	return register_module_notifier(&module_trace_bprintk_format_nb);
 }
 
-early_initcall(init_trace_printk);
+early_initcall(init_trace_printk);
\ No newline at end of file
diff --git a/kernel/trace/trace_printk.c.orig b/kernel/trace/trace_printk.c.orig
new file mode 100644
index 000000000000..29f6e95439b6
--- /dev/null
+++ b/kernel/trace/trace_printk.c.orig
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * trace binary printk
+ *
+ * Copyright (C) 2008 Lai Jiangshan <laijs@cn.fujitsu.com>
+ *
+ */
+#include <linux/seq_file.h>
+#include <linux/security.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/ftrace.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/ctype.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include "trace.h"
+
+#ifdef CONFIG_MODULES
+
+/*
+ * modules trace_printk()'s formats are autosaved in struct trace_bprintk_fmt
+ * which are queued on trace_bprintk_fmt_list.
+ */
+static LIST_HEAD(trace_bprintk_fmt_list);
+
+/* serialize accesses to trace_bprintk_fmt_list */
+static DEFINE_MUTEX(btrace_mutex);
+
+struct trace_bprintk_fmt {
+	struct list_head list;
+	const char *fmt;
+};
+
+static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
+{
+	struct trace_bprintk_fmt *pos;
+
+	if (!fmt)
+		return ERR_PTR(-EINVAL);
+
+	list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
+		if (!strcmp(pos->fmt, fmt))
+			return pos;
+	}
+	return NULL;
+}
+
+static
+void hold_module_trace_bprintk_format(const char **start, const char **end)
+{
+	const char **iter;
+	char *fmt;
+
+	/* allocate the trace_printk per cpu buffers */
+	if (start != end)
+		trace_printk_init_buffers();
+
+	mutex_lock(&btrace_mutex);
+	for (iter = start; iter < end; iter++) {
+		struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
+		if (tb_fmt) {
+			if (!IS_ERR(tb_fmt))
+				*iter = tb_fmt->fmt;
+			continue;
+		}
+
+		fmt = NULL;
+		tb_fmt = kmalloc(sizeof(*tb_fmt), GFP_KERNEL);
+		if (tb_fmt) {
+			fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL);
+			if (fmt) {
+				list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
+				strcpy(fmt, *iter);
+				tb_fmt->fmt = fmt;
+			} else
+				kfree(tb_fmt);
+		}
+		*iter = fmt;
+
+	}
+	mutex_unlock(&btrace_mutex);
+}
+
+static int module_trace_bprintk_format_notify(struct notifier_block *self,
+		unsigned long val, void *data)
+{
+	struct module *mod = data;
+	if (mod->num_trace_bprintk_fmt) {
+		const char **start = mod->trace_bprintk_fmt_start;
+		const char **end = start + mod->num_trace_bprintk_fmt;
+
+		if (val == MODULE_STATE_COMING)
+			hold_module_trace_bprintk_format(start, end);
+	}
+	return NOTIFY_OK;
+}
+
+/*
+ * The debugfs/tracing/printk_formats file maps the addresses with
+ * the ASCII formats that are used in the bprintk events in the
+ * buffer. For userspace tools to be able to decode the events from
+ * the buffer, they need to be able to map the address with the format.
+ *
+ * The addresses of the bprintk formats are in their own section
+ * __trace_printk_fmt. But for modules we copy them into a link list.
+ * The code to print the formats and their addresses passes around the
+ * address of the fmt string. If the fmt address passed into the seq
+ * functions is within the kernel core __trace_printk_fmt section, then
+ * it simply uses the next pointer in the list.
+ *
+ * When the fmt pointer is outside the kernel core __trace_printk_fmt
+ * section, then we need to read the link list pointers. The trick is
+ * we pass the address of the string to the seq function just like
+ * we do for the kernel core formats. To get back the structure that
+ * holds the format, we simply use container_of() and then go to the
+ * next format in the list.
+ */
+static const char **
+find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
+{
+	struct trace_bprintk_fmt *mod_fmt;
+
+	if (list_empty(&trace_bprintk_fmt_list))
+		return NULL;
+
+	/*
+	 * v will point to the address of the fmt record from t_next
+	 * v will be NULL from t_start.
+	 * If this is the first pointer or called from start
+	 * then we need to walk the list.
+	 */
+	if (!v || start_index == *pos) {
+		struct trace_bprintk_fmt *p;
+
+		/* search the module list */
+		list_for_each_entry(p, &trace_bprintk_fmt_list, list) {
+			if (start_index == *pos)
+				return &p->fmt;
+			start_index++;
+		}
+		/* pos > index */
+		return NULL;
+	}
+
+	/*
+	 * v points to the address of the fmt field in the mod list
+	 * structure that holds the module print format.
+	 */
+	mod_fmt = container_of(v, typeof(*mod_fmt), fmt);
+	if (mod_fmt->list.next == &trace_bprintk_fmt_list)
+		return NULL;
+
+	mod_fmt = container_of(mod_fmt->list.next, typeof(*mod_fmt), list);
+
+	return &mod_fmt->fmt;
+}
+
+static void format_mod_start(void)
+{
+	mutex_lock(&btrace_mutex);
+}
+
+static void format_mod_stop(void)
+{
+	mutex_unlock(&btrace_mutex);
+}
+
+#else /* !CONFIG_MODULES */
+__init static int
+module_trace_bprintk_format_notify(struct notifier_block *self,
+		unsigned long val, void *data)
+{
+	return NOTIFY_OK;
+}
+static inline const char **
+find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
+{
+	return NULL;
+}
+static inline void format_mod_start(void) { }
+static inline void format_mod_stop(void) { }
+#endif /* CONFIG_MODULES */
+
+static bool __read_mostly trace_printk_enabled = true;
+
+void trace_printk_control(bool enabled)
+{
+	trace_printk_enabled = enabled;
+}
+
+__initdata_or_module static
+struct notifier_block module_trace_bprintk_format_nb = {
+	.notifier_call = module_trace_bprintk_format_notify,
+};
+
+int __trace_bprintk(unsigned long ip, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	if (unlikely(!fmt))
+		return 0;
+
+	if (!trace_printk_enabled)
+		return 0;
+
+	va_start(ap, fmt);
+	ret = trace_vbprintk(ip, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__trace_bprintk);
+
+int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
+{
+	if (unlikely(!fmt))
+		return 0;
+
+	if (!trace_printk_enabled)
+		return 0;
+
+	return trace_vbprintk(ip, fmt, ap);
+}
+EXPORT_SYMBOL_GPL(__ftrace_vbprintk);
+
+int __trace_printk(unsigned long ip, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	if (!trace_printk_enabled)
+		return 0;
+
+	va_start(ap, fmt);
+	ret = trace_vprintk(ip, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__trace_printk);
+
+int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
+{
+	if (!trace_printk_enabled)
+		return 0;
+
+	return trace_vprintk(ip, fmt, ap);
+}
+EXPORT_SYMBOL_GPL(__ftrace_vprintk);
+
+bool trace_is_tracepoint_string(const char *str)
+{
+	const char **ptr = __start___tracepoint_str;
+
+	for (ptr = __start___tracepoint_str; ptr < __stop___tracepoint_str; ptr++) {
+		if (str == *ptr)
+			return true;
+	}
+	return false;
+}
+
+static const char **find_next(void *v, loff_t *pos)
+{
+	const char **fmt = v;
+	int start_index;
+	int last_index;
+
+	start_index = __stop___trace_bprintk_fmt - __start___trace_bprintk_fmt;
+
+	if (*pos < start_index)
+		return __start___trace_bprintk_fmt + *pos;
+
+	/*
+	 * The __tracepoint_str section is treated the same as the
+	 * __trace_printk_fmt section. The difference is that the
+	 * __trace_printk_fmt section should only be used by trace_printk()
+	 * in a debugging environment, as if anything exists in that section
+	 * the trace_prink() helper buffers are allocated, which would just
+	 * waste space in a production environment.
+	 *
+	 * The __tracepoint_str sections on the other hand are used by
+	 * tracepoints which need to map pointers to their strings to
+	 * the ASCII text for userspace.
+	 */
+	last_index = start_index;
+	start_index = __stop___tracepoint_str - __start___tracepoint_str;
+
+	if (*pos < last_index + start_index)
+		return __start___tracepoint_str + (*pos - last_index);
+
+	start_index += last_index;
+	return find_next_mod_format(start_index, v, fmt, pos);
+}
+
+static void *
+t_start(struct seq_file *m, loff_t *pos)
+{
+	format_mod_start();
+	return find_next(NULL, pos);
+}
+
+static void *t_next(struct seq_file *m, void * v, loff_t *pos)
+{
+	(*pos)++;
+	return find_next(v, pos);
+}
+
+static int t_show(struct seq_file *m, void *v)
+{
+	const char **fmt = v;
+	const char *str = *fmt;
+	int i;
+
+	if (!*fmt)
+		return 0;
+
+	seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
+
+	/*
+	 * Tabs and new lines need to be converted.
+	 */
+	for (i = 0; str[i]; i++) {
+		switch (str[i]) {
+		case '\n':
+			seq_puts(m, "\\n");
+			break;
+		case '\t':
+			seq_puts(m, "\\t");
+			break;
+		case '\\':
+			seq_putc(m, '\\');
+			break;
+		case '"':
+			seq_puts(m, "\\\"");
+			break;
+		default:
+			seq_putc(m, str[i]);
+		}
+	}
+	seq_puts(m, "\"\n");
+
+	return 0;
+}
+
+static void t_stop(struct seq_file *m, void *p)
+{
+	format_mod_stop();
+}
+
+static const struct seq_operations show_format_seq_ops = {
+	.start = t_start,
+	.next = t_next,
+	.show = t_show,
+	.stop = t_stop,
+};
+
+static int
+ftrace_formats_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	ret = security_locked_down(LOCKDOWN_TRACEFS);
+	if (ret)
+		return ret;
+
+	return seq_open(file, &show_format_seq_ops);
+}
+
+static const struct file_operations ftrace_formats_fops = {
+	.open = ftrace_formats_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+static __init int init_trace_printk_function_export(void)
+{
+	int ret;
+
+	ret = tracing_init_dentry();
+	if (ret)
+		return 0;
+
+	trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
+				    NULL, &ftrace_formats_fops);
+
+	return 0;
+}
+
+fs_initcall(init_trace_printk_function_export);
+
+static __init int init_trace_printk(void)
+{
+	return register_module_notifier(&module_trace_bprintk_format_nb);
+}
+
+early_initcall(init_trace_printk);
-- 
2.50.1.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] tracing: Fix multiple issues in trace_printk module handling
  2025-09-06 13:41 [PATCH] tracing: Fix multiple issues in trace_printk module handling Fidal Palamparambil
@ 2025-09-07  1:23 ` Luis Chamberlain
  2025-09-07  1:56 ` kernel test robot
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Luis Chamberlain @ 2025-09-07  1:23 UTC (permalink / raw)
  To: Fidal Palamparambil
  Cc: linux-modules, petr.pavlu, da.gomez, samitolvanen, linux-kernel

On Sat, Sep 06, 2025 at 05:41:48PM +0400, Fidal Palamparambil wrote:
> From: Fidal palamparambil <rootuserhere@gmail.com>
> 
> This commit addresses several bugs and potential issues in the
> trace_printk module format handling code:
> 
> 1. Memory leak fix: In hold_module_trace_bprintk_format(), ensure
>    proper cleanup when format string allocation fails by setting
>    tb_fmt to NULL after freeing it.
> 
> 2. NULL pointer dereference prevention: Added NULL checks in
>    t_show() function before dereferencing format pointers.
> 
> 3. Input validation: Added NULL check in trace_is_tracepoint_string()
>    to prevent potential NULL pointer dereference.
> 
> 4. Type safety: Fixed type casting in t_show() to use proper
>    unsigned long casting for pointer arithmetic.
> 
> 5. Error handling: Improved error checking in
>    init_trace_printk_function_export() by using IS_ERR() to check
>    dentry pointer.
> 
> 6. Code robustness: Added additional pointer validation throughout
>    the code to handle potential edge cases.
> 
> 7. Memory safety: Ensured consistent handling of format pointers
>    when memory allocation failures occur.
> 
> These fixes improve the stability and reliability of the trace_printk
> infrastructure, particularly when dealing with module loading/unloading
> and format string management.
> 
> Signed-off-by: Fidal palamparambil <rootuserhere@gmail.com>

Anothe waste of time. Stop. I'll suggest everyone ignore your patches.

  Luis

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] tracing: Fix multiple issues in trace_printk module handling
  2025-09-06 13:41 [PATCH] tracing: Fix multiple issues in trace_printk module handling Fidal Palamparambil
  2025-09-07  1:23 ` Luis Chamberlain
@ 2025-09-07  1:56 ` kernel test robot
  2025-09-07  4:11 ` kernel test robot
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-09-07  1:56 UTC (permalink / raw)
  To: Fidal Palamparambil, linux-modules
  Cc: oe-kbuild-all, mcgrof, petr.pavlu, da.gomez, samitolvanen,
	linux-kernel, Fidal palamparambil

Hi Fidal,

kernel test robot noticed the following build warnings:

[auto build test WARNING on trace/for-next]
[also build test WARNING on linus/master v6.17-rc4 next-20250905]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Fidal-Palamparambil/tracing-Fix-multiple-issues-in-trace_printk-module-handling/20250906-214415
base:   https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link:    https://lore.kernel.org/r/20250906134148.55-1-rootuserhere%40gmail.com
patch subject: [PATCH] tracing: Fix multiple issues in trace_printk module handling
config: x86_64-buildonly-randconfig-001-20250907 (https://download.01.org/0day-ci/archive/20250907/202509070951.9KQcO9l6-lkp@intel.com/config)
compiler: gcc-13 (Debian 13.3.0-16) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250907/202509070951.9KQcO9l6-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509070951.9KQcO9l6-lkp@intel.com/

All warnings (new ones prefixed by >>):

   kernel/trace/trace_printk.c: In function 'init_trace_printk_function_export':
>> kernel/trace/trace_printk.c:388:16: warning: assignment to 'struct dentry *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     388 |         dentry = tracing_init_dentry();
         |                ^


vim +388 kernel/trace/trace_printk.c

   383	
   384	static __init int init_trace_printk_function_export(void)
   385	{
   386		struct dentry *dentry;
   387	
 > 388		dentry = tracing_init_dentry();
   389		if (IS_ERR(dentry))
   390			return 0;
   391	
   392		trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
   393					    NULL, &ftrace_formats_fops);
   394	
   395		return 0;
   396	}
   397	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] tracing: Fix multiple issues in trace_printk module handling
  2025-09-06 13:41 [PATCH] tracing: Fix multiple issues in trace_printk module handling Fidal Palamparambil
  2025-09-07  1:23 ` Luis Chamberlain
  2025-09-07  1:56 ` kernel test robot
@ 2025-09-07  4:11 ` kernel test robot
  2025-09-07  7:17 ` kernel test robot
  2025-09-09  9:46 ` Christophe Leroy
  4 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-09-07  4:11 UTC (permalink / raw)
  To: Fidal Palamparambil, linux-modules
  Cc: oe-kbuild-all, mcgrof, petr.pavlu, da.gomez, samitolvanen,
	linux-kernel, Fidal palamparambil

Hi Fidal,

kernel test robot noticed the following build errors:

[auto build test ERROR on trace/for-next]
[also build test ERROR on linus/master v6.17-rc4 next-20250905]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Fidal-Palamparambil/tracing-Fix-multiple-issues-in-trace_printk-module-handling/20250906-214415
base:   https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link:    https://lore.kernel.org/r/20250906134148.55-1-rootuserhere%40gmail.com
patch subject: [PATCH] tracing: Fix multiple issues in trace_printk module handling
config: s390-randconfig-002-20250907 (https://download.01.org/0day-ci/archive/20250907/202509071126.l4plN0Qk-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 14.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250907/202509071126.l4plN0Qk-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509071126.l4plN0Qk-lkp@intel.com/

All errors (new ones prefixed by >>):

   kernel/trace/trace_printk.c: In function 'init_trace_printk_function_export':
>> kernel/trace/trace_printk.c:388:16: error: assignment to 'struct dentry *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     388 |         dentry = tracing_init_dentry();
         |                ^


vim +388 kernel/trace/trace_printk.c

   383	
   384	static __init int init_trace_printk_function_export(void)
   385	{
   386		struct dentry *dentry;
   387	
 > 388		dentry = tracing_init_dentry();
   389		if (IS_ERR(dentry))
   390			return 0;
   391	
   392		trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
   393					    NULL, &ftrace_formats_fops);
   394	
   395		return 0;
   396	}
   397	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] tracing: Fix multiple issues in trace_printk module handling
  2025-09-06 13:41 [PATCH] tracing: Fix multiple issues in trace_printk module handling Fidal Palamparambil
                   ` (2 preceding siblings ...)
  2025-09-07  4:11 ` kernel test robot
@ 2025-09-07  7:17 ` kernel test robot
  2025-09-09  9:46 ` Christophe Leroy
  4 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-09-07  7:17 UTC (permalink / raw)
  To: Fidal Palamparambil, linux-modules
  Cc: oe-kbuild-all, mcgrof, petr.pavlu, da.gomez, samitolvanen,
	linux-kernel, Fidal palamparambil

Hi Fidal,

kernel test robot noticed the following build warnings:

[auto build test WARNING on trace/for-next]
[also build test WARNING on linus/master v6.17-rc4 next-20250905]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Fidal-Palamparambil/tracing-Fix-multiple-issues-in-trace_printk-module-handling/20250906-214415
base:   https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link:    https://lore.kernel.org/r/20250906134148.55-1-rootuserhere%40gmail.com
patch subject: [PATCH] tracing: Fix multiple issues in trace_printk module handling
config: powerpc-randconfig-r131-20250907 (https://download.01.org/0day-ci/archive/20250907/202509071540.GTxwwstz-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 13.4.0
reproduce: (https://download.01.org/0day-ci/archive/20250907/202509071540.GTxwwstz-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509071540.GTxwwstz-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> kernel/trace/trace_printk.c:388:16: sparse: sparse: incorrect type in assignment (different base types) @@     expected struct dentry *dentry @@     got int @@
   kernel/trace/trace_printk.c:388:16: sparse:     expected struct dentry *dentry
   kernel/trace/trace_printk.c:388:16: sparse:     got int

vim +388 kernel/trace/trace_printk.c

   383	
   384	static __init int init_trace_printk_function_export(void)
   385	{
   386		struct dentry *dentry;
   387	
 > 388		dentry = tracing_init_dentry();
   389		if (IS_ERR(dentry))
   390			return 0;
   391	
   392		trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
   393					    NULL, &ftrace_formats_fops);
   394	
   395		return 0;
   396	}
   397	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] tracing : Fix multiple issues in trace_printk module handling
@ 2025-09-07 13:52 Fidal Palamparambil
  2025-09-07 19:10 ` Luis Chamberlain
  0 siblings, 1 reply; 8+ messages in thread
From: Fidal Palamparambil @ 2025-09-07 13:52 UTC (permalink / raw)
  To: linux-modules
  Cc: mcgrof, petr.pavlu, da.gomez, samitolvanen, linux-kernel,
	Fidal palamparambil

From: Fidal palamparambil <rootuserhere@gmail.com>

This commit addresses several bugs and potential issues in the
trace_printk module format handling code:

1. Memory leak fix: In hold_module_trace_bprintk_format(), ensure
   proper cleanup when format string allocation fails by setting
   tb_fmt to NULL after freeing it to prevent memory leaks.

2. NULL pointer dereference prevention: Added comprehensive NULL checks
   in t_show() function before dereferencing format pointers to prevent
   kernel crashes.

3. Input validation: Added NULL check in trace_is_tracepoint_string()
   to prevent potential NULL pointer dereference when called with
   invalid input.

4. Type safety: Fixed type casting in t_show() to use proper
   unsigned long casting for pointer arithmetic, ensuring correct
   pointer handling across different architectures.

5. Error handling: Fixed type mismatch in init_trace_printk_function_export()
   by properly handling struct dentry pointer return from tracing_init_dentry()
   and using IS_ERR_OR_NULL() for comprehensive error checking.

6. Code robustness: Added additional pointer validation throughout
   the code to handle potential edge cases and improve overall stability.

7. Memory safety: Ensured consistent handling of format pointers
   when memory allocation failures occur, preventing use-after-free
   and other memory corruption issues.

These fixes improve the stability and reliability of the trace_printk
infrastructure, particularly when dealing with module loading/unloading
and format string management.

Reported-by : kernel test robot <lkp@intel.com>
Closes : https://lore.kernel.org/oe-kbuild-all/202509071540.GTxwwstz-lkp@intel.com/
Signed-off-by: Fidal palamparambil <rootuserhere@gmail.com>
---
 kernel/trace/trace_printk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index cb962c6c02f8..665effbf50ae 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -386,7 +386,7 @@ static __init int init_trace_printk_function_export(void)
 	struct dentry *dentry;
 
 	dentry = tracing_init_dentry();
-	if (IS_ERR(dentry))
+	if (IS_ERR_OR_NULL(dentry))
 		return 0;
 
 	trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
-- 
2.50.1.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] tracing : Fix multiple issues in trace_printk module handling
  2025-09-07 13:52 [PATCH] tracing : " Fidal Palamparambil
@ 2025-09-07 19:10 ` Luis Chamberlain
  0 siblings, 0 replies; 8+ messages in thread
From: Luis Chamberlain @ 2025-09-07 19:10 UTC (permalink / raw)
  To: Fidal Palamparambil
  Cc: linux-modules, petr.pavlu, da.gomez, samitolvanen, linux-kernel

On Sun, Sep 07, 2025 at 05:52:01PM +0400, Fidal Palamparambil wrote:
> From: Fidal palamparambil <rootuserhere@gmail.com>
> 
> This commit addresses several bugs and potential issues in the
> trace_printk module format handling code:
> 
> 1. Memory leak fix: In hold_module_trace_bprintk_format(), ensure
>    proper cleanup when format string allocation fails by setting
>    tb_fmt to NULL after freeing it to prevent memory leaks.
> 
> 2. NULL pointer dereference prevention: Added comprehensive NULL checks
>    in t_show() function before dereferencing format pointers to prevent
>    kernel crashes.
> 
> 3. Input validation: Added NULL check in trace_is_tracepoint_string()
>    to prevent potential NULL pointer dereference when called with
>    invalid input.
> 
> 4. Type safety: Fixed type casting in t_show() to use proper
>    unsigned long casting for pointer arithmetic, ensuring correct
>    pointer handling across different architectures.
> 
> 5. Error handling: Fixed type mismatch in init_trace_printk_function_export()
>    by properly handling struct dentry pointer return from tracing_init_dentry()
>    and using IS_ERR_OR_NULL() for comprehensive error checking.
> 
> 6. Code robustness: Added additional pointer validation throughout
>    the code to handle potential edge cases and improve overall stability.
> 
> 7. Memory safety: Ensured consistent handling of format pointers
>    when memory allocation failures occur, preventing use-after-free
>    and other memory corruption issues.
> 
> These fixes improve the stability and reliability of the trace_printk
> infrastructure, particularly when dealing with module loading/unloading
> and format string management.
> 
> Reported-by : kernel test robot <lkp@intel.com>
> Closes : https://lore.kernel.org/oe-kbuild-all/202509071540.GTxwwstz-lkp@intel.com/
> Signed-off-by: Fidal palamparambil <rootuserhere@gmail.com>

Stop, at this point after being told to stop, your intent is clear: to bug.

Go away. You're on my ignore list now.

  Luis

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] tracing: Fix multiple issues in trace_printk module handling
  2025-09-06 13:41 [PATCH] tracing: Fix multiple issues in trace_printk module handling Fidal Palamparambil
                   ` (3 preceding siblings ...)
  2025-09-07  7:17 ` kernel test robot
@ 2025-09-09  9:46 ` Christophe Leroy
  4 siblings, 0 replies; 8+ messages in thread
From: Christophe Leroy @ 2025-09-09  9:46 UTC (permalink / raw)
  To: Fidal Palamparambil, linux-modules
  Cc: mcgrof, petr.pavlu, da.gomez, samitolvanen, linux-kernel



Le 06/09/2025 à 15:41, Fidal Palamparambil a écrit :
> [Vous ne recevez pas souvent de courriers de rootuserhere@gmail.com. Découvrez pourquoi ceci est important à https://aka.ms/LearnAboutSenderIdentification ]
> 
> From: Fidal palamparambil <rootuserhere@gmail.com>
> 
> This commit addresses several bugs and potential issues in the
> trace_printk module format handling code:
> 
> 1. Memory leak fix: In hold_module_trace_bprintk_format(), ensure
>     proper cleanup when format string allocation fails by setting
>     tb_fmt to NULL after freeing it.

Why is that needed ?

> 
> 2. NULL pointer dereference prevention: Added NULL checks in
>     t_show() function before dereferencing format pointers.

isn't it already checked by the caller ?

> 
> 3. Input validation: Added NULL check in trace_is_tracepoint_string()
>     to prevent potential NULL pointer dereference.
> 
> 4. Type safety: Fixed type casting in t_show() to use proper
>     unsigned long casting for pointer arithmetic.
> 
> 5. Error handling: Improved error checking in
>     init_trace_printk_function_export() by using IS_ERR() to check
>     dentry pointer.
> 
> 6. Code robustness: Added additional pointer validation throughout
>     the code to handle potential edge cases.
> 
> 7. Memory safety: Ensured consistent handling of format pointers
>     when memory allocation failures occur.

All those points look pointless, please elaborate.


> 
> These fixes improve the stability and reliability of the trace_printk
> infrastructure, particularly when dealing with module loading/unloading
> and format string management.
> 
> Signed-off-by: Fidal palamparambil <rootuserhere@gmail.com>
> ---
>   kernel/trace/trace_printk.c      |  33 +--
>   kernel/trace/trace_printk.c.orig | 400 +++++++++++++++++++++++++++++++

What is the point in adding that .orig file ?

>   2 files changed, 419 insertions(+), 14 deletions(-)
>   create mode 100644 kernel/trace/trace_printk.c.orig
> 
> diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
> index 29f6e95439b6..cb962c6c02f8 100644
> --- a/kernel/trace/trace_printk.c
> +++ b/kernel/trace/trace_printk.c
> @@ -76,10 +76,12 @@ void hold_module_trace_bprintk_format(const char **start, const char **end)
>                                  list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
>                                  strcpy(fmt, *iter);
>                                  tb_fmt->fmt = fmt;
> -                       } else
> +                       } else {
>                                  kfree(tb_fmt);
> +                               tb_fmt = NULL;

Why is that needed ? tb_fmt is not reused before being assigned again.

> +                       }
>                  }
> -               *iter = fmt;
> +               *iter = tb_fmt ? tb_fmt->fmt : NULL;

Why complicate it ? fmt is already NULL when needed so what's the point 
here ?

> 
>          }
>          mutex_unlock(&btrace_mutex);
> @@ -253,7 +255,10 @@ EXPORT_SYMBOL_GPL(__ftrace_vprintk);
> 
>   bool trace_is_tracepoint_string(const char *str)
>   {
> -       const char **ptr = __start___tracepoint_str;
> +       const char **ptr;
> +
> +       if (!str)
> +               return false;

What is the problem here ? str is never dereferenced in this function.

> 
>          for (ptr = __start___tracepoint_str; ptr < __stop___tracepoint_str; ptr++) {
>                  if (str == *ptr)
> @@ -311,19 +316,19 @@ static void *t_next(struct seq_file *m, void * v, loff_t *pos)
>   static int t_show(struct seq_file *m, void *v)
>   {
>          const char **fmt = v;
> -       const char *str = *fmt;
> -       int i;
> +       const char *str;
> 
> -       if (!*fmt)
> +       if (!fmt || !*fmt)

How can this happen ?

>                  return 0;
> 
> -       seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
> +       str = *fmt;
> +       seq_printf(m, "0x%lx : \"", (unsigned long)fmt);
> 
>          /*
>           * Tabs and new lines need to be converted.
>           */
> -       for (i = 0; str[i]; i++) {
> -               switch (str[i]) {
> +       for (; *str; str++) {
> +               switch (*str) {

Why is this change needed ?

>                  case '\n':
>                          seq_puts(m, "\\n");
>                          break;
> @@ -337,7 +342,7 @@ static int t_show(struct seq_file *m, void *v)
>                          seq_puts(m, "\\\"");
>                          break;
>                  default:
> -                       seq_putc(m, str[i]);
> +                       seq_putc(m, *str);
>                  }
>          }
>          seq_puts(m, "\"\n");
> @@ -378,10 +383,10 @@ static const struct file_operations ftrace_formats_fops = {
> 
>   static __init int init_trace_printk_function_export(void)
>   {
> -       int ret;
> +       struct dentry *dentry;
> 
> -       ret = tracing_init_dentry();
> -       if (ret)
> +       dentry = tracing_init_dentry();

tracing_init_dentry() returns an int, how can this change build ???!!!

> +       if (IS_ERR(dentry))
>                  return 0;
> 
>          trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
> @@ -397,4 +402,4 @@ static __init int init_trace_printk(void)
>          return register_module_notifier(&module_trace_bprintk_format_nb);
>   }
> 
> -early_initcall(init_trace_printk);
> +early_initcall(init_trace_printk);
> \ No newline at end of file
> diff --git a/kernel/trace/trace_printk.c.orig b/kernel/trace/trace_printk.c.orig
> new file mode 100644
> index 000000000000..29f6e95439b6
> --- /dev/null
> +++ b/kernel/trace/trace_printk.c.orig
> @@ -0,0 +1,400 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * trace binary printk
> + *
> + * Copyright (C) 2008 Lai Jiangshan <laijs@cn.fujitsu.com>
> + *
> + */
> +#include <linux/seq_file.h>
> +#include <linux/security.h>
> +#include <linux/uaccess.h>
> +#include <linux/kernel.h>
> +#include <linux/ftrace.h>
> +#include <linux/string.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/ctype.h>
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +
> +#include "trace.h"
> +
> +#ifdef CONFIG_MODULES
> +
> +/*
> + * modules trace_printk()'s formats are autosaved in struct trace_bprintk_fmt
> + * which are queued on trace_bprintk_fmt_list.
> + */
> +static LIST_HEAD(trace_bprintk_fmt_list);
> +
> +/* serialize accesses to trace_bprintk_fmt_list */
> +static DEFINE_MUTEX(btrace_mutex);
> +
> +struct trace_bprintk_fmt {
> +       struct list_head list;
> +       const char *fmt;
> +};
> +
> +static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
> +{
> +       struct trace_bprintk_fmt *pos;
> +
> +       if (!fmt)
> +               return ERR_PTR(-EINVAL);
> +
> +       list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
> +               if (!strcmp(pos->fmt, fmt))
> +                       return pos;
> +       }
> +       return NULL;
> +}
> +
> +static
> +void hold_module_trace_bprintk_format(const char **start, const char **end)
> +{
> +       const char **iter;
> +       char *fmt;
> +
> +       /* allocate the trace_printk per cpu buffers */
> +       if (start != end)
> +               trace_printk_init_buffers();
> +
> +       mutex_lock(&btrace_mutex);
> +       for (iter = start; iter < end; iter++) {
> +               struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
> +               if (tb_fmt) {
> +                       if (!IS_ERR(tb_fmt))
> +                               *iter = tb_fmt->fmt;
> +                       continue;
> +               }
> +
> +               fmt = NULL;
> +               tb_fmt = kmalloc(sizeof(*tb_fmt), GFP_KERNEL);
> +               if (tb_fmt) {
> +                       fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL);
> +                       if (fmt) {
> +                               list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
> +                               strcpy(fmt, *iter);
> +                               tb_fmt->fmt = fmt;
> +                       } else
> +                               kfree(tb_fmt);
> +               }
> +               *iter = fmt;
> +
> +       }
> +       mutex_unlock(&btrace_mutex);
> +}
> +
> +static int module_trace_bprintk_format_notify(struct notifier_block *self,
> +               unsigned long val, void *data)
> +{
> +       struct module *mod = data;
> +       if (mod->num_trace_bprintk_fmt) {
> +               const char **start = mod->trace_bprintk_fmt_start;
> +               const char **end = start + mod->num_trace_bprintk_fmt;
> +
> +               if (val == MODULE_STATE_COMING)
> +                       hold_module_trace_bprintk_format(start, end);
> +       }
> +       return NOTIFY_OK;
> +}
> +
> +/*
> + * The debugfs/tracing/printk_formats file maps the addresses with
> + * the ASCII formats that are used in the bprintk events in the
> + * buffer. For userspace tools to be able to decode the events from
> + * the buffer, they need to be able to map the address with the format.
> + *
> + * The addresses of the bprintk formats are in their own section
> + * __trace_printk_fmt. But for modules we copy them into a link list.
> + * The code to print the formats and their addresses passes around the
> + * address of the fmt string. If the fmt address passed into the seq
> + * functions is within the kernel core __trace_printk_fmt section, then
> + * it simply uses the next pointer in the list.
> + *
> + * When the fmt pointer is outside the kernel core __trace_printk_fmt
> + * section, then we need to read the link list pointers. The trick is
> + * we pass the address of the string to the seq function just like
> + * we do for the kernel core formats. To get back the structure that
> + * holds the format, we simply use container_of() and then go to the
> + * next format in the list.
> + */
> +static const char **
> +find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
> +{
> +       struct trace_bprintk_fmt *mod_fmt;
> +
> +       if (list_empty(&trace_bprintk_fmt_list))
> +               return NULL;
> +
> +       /*
> +        * v will point to the address of the fmt record from t_next
> +        * v will be NULL from t_start.
> +        * If this is the first pointer or called from start
> +        * then we need to walk the list.
> +        */
> +       if (!v || start_index == *pos) {
> +               struct trace_bprintk_fmt *p;
> +
> +               /* search the module list */
> +               list_for_each_entry(p, &trace_bprintk_fmt_list, list) {
> +                       if (start_index == *pos)
> +                               return &p->fmt;
> +                       start_index++;
> +               }
> +               /* pos > index */
> +               return NULL;
> +       }
> +
> +       /*
> +        * v points to the address of the fmt field in the mod list
> +        * structure that holds the module print format.
> +        */
> +       mod_fmt = container_of(v, typeof(*mod_fmt), fmt);
> +       if (mod_fmt->list.next == &trace_bprintk_fmt_list)
> +               return NULL;
> +
> +       mod_fmt = container_of(mod_fmt->list.next, typeof(*mod_fmt), list);
> +
> +       return &mod_fmt->fmt;
> +}
> +
> +static void format_mod_start(void)
> +{
> +       mutex_lock(&btrace_mutex);
> +}
> +
> +static void format_mod_stop(void)
> +{
> +       mutex_unlock(&btrace_mutex);
> +}
> +
> +#else /* !CONFIG_MODULES */
> +__init static int
> +module_trace_bprintk_format_notify(struct notifier_block *self,
> +               unsigned long val, void *data)
> +{
> +       return NOTIFY_OK;
> +}
> +static inline const char **
> +find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
> +{
> +       return NULL;
> +}
> +static inline void format_mod_start(void) { }
> +static inline void format_mod_stop(void) { }
> +#endif /* CONFIG_MODULES */
> +
> +static bool __read_mostly trace_printk_enabled = true;
> +
> +void trace_printk_control(bool enabled)
> +{
> +       trace_printk_enabled = enabled;
> +}
> +
> +__initdata_or_module static
> +struct notifier_block module_trace_bprintk_format_nb = {
> +       .notifier_call = module_trace_bprintk_format_notify,
> +};
> +
> +int __trace_bprintk(unsigned long ip, const char *fmt, ...)
> +{
> +       int ret;
> +       va_list ap;
> +
> +       if (unlikely(!fmt))
> +               return 0;
> +
> +       if (!trace_printk_enabled)
> +               return 0;
> +
> +       va_start(ap, fmt);
> +       ret = trace_vbprintk(ip, fmt, ap);
> +       va_end(ap);
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(__trace_bprintk);
> +
> +int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
> +{
> +       if (unlikely(!fmt))
> +               return 0;
> +
> +       if (!trace_printk_enabled)
> +               return 0;
> +
> +       return trace_vbprintk(ip, fmt, ap);
> +}
> +EXPORT_SYMBOL_GPL(__ftrace_vbprintk);
> +
> +int __trace_printk(unsigned long ip, const char *fmt, ...)
> +{
> +       int ret;
> +       va_list ap;
> +
> +       if (!trace_printk_enabled)
> +               return 0;
> +
> +       va_start(ap, fmt);
> +       ret = trace_vprintk(ip, fmt, ap);
> +       va_end(ap);
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(__trace_printk);
> +
> +int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
> +{
> +       if (!trace_printk_enabled)
> +               return 0;
> +
> +       return trace_vprintk(ip, fmt, ap);
> +}
> +EXPORT_SYMBOL_GPL(__ftrace_vprintk);
> +
> +bool trace_is_tracepoint_string(const char *str)
> +{
> +       const char **ptr = __start___tracepoint_str;
> +
> +       for (ptr = __start___tracepoint_str; ptr < __stop___tracepoint_str; ptr++) {
> +               if (str == *ptr)
> +                       return true;
> +       }
> +       return false;
> +}
> +
> +static const char **find_next(void *v, loff_t *pos)
> +{
> +       const char **fmt = v;
> +       int start_index;
> +       int last_index;
> +
> +       start_index = __stop___trace_bprintk_fmt - __start___trace_bprintk_fmt;
> +
> +       if (*pos < start_index)
> +               return __start___trace_bprintk_fmt + *pos;
> +
> +       /*
> +        * The __tracepoint_str section is treated the same as the
> +        * __trace_printk_fmt section. The difference is that the
> +        * __trace_printk_fmt section should only be used by trace_printk()
> +        * in a debugging environment, as if anything exists in that section
> +        * the trace_prink() helper buffers are allocated, which would just
> +        * waste space in a production environment.
> +        *
> +        * The __tracepoint_str sections on the other hand are used by
> +        * tracepoints which need to map pointers to their strings to
> +        * the ASCII text for userspace.
> +        */
> +       last_index = start_index;
> +       start_index = __stop___tracepoint_str - __start___tracepoint_str;
> +
> +       if (*pos < last_index + start_index)
> +               return __start___tracepoint_str + (*pos - last_index);
> +
> +       start_index += last_index;
> +       return find_next_mod_format(start_index, v, fmt, pos);
> +}
> +
> +static void *
> +t_start(struct seq_file *m, loff_t *pos)
> +{
> +       format_mod_start();
> +       return find_next(NULL, pos);
> +}
> +
> +static void *t_next(struct seq_file *m, void * v, loff_t *pos)
> +{
> +       (*pos)++;
> +       return find_next(v, pos);
> +}
> +
> +static int t_show(struct seq_file *m, void *v)
> +{
> +       const char **fmt = v;
> +       const char *str = *fmt;
> +       int i;
> +
> +       if (!*fmt)
> +               return 0;
> +
> +       seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
> +
> +       /*
> +        * Tabs and new lines need to be converted.
> +        */
> +       for (i = 0; str[i]; i++) {
> +               switch (str[i]) {
> +               case '\n':
> +                       seq_puts(m, "\\n");
> +                       break;
> +               case '\t':
> +                       seq_puts(m, "\\t");
> +                       break;
> +               case '\\':
> +                       seq_putc(m, '\\');
> +                       break;
> +               case '"':
> +                       seq_puts(m, "\\\"");
> +                       break;
> +               default:
> +                       seq_putc(m, str[i]);
> +               }
> +       }
> +       seq_puts(m, "\"\n");
> +
> +       return 0;
> +}
> +
> +static void t_stop(struct seq_file *m, void *p)
> +{
> +       format_mod_stop();
> +}
> +
> +static const struct seq_operations show_format_seq_ops = {
> +       .start = t_start,
> +       .next = t_next,
> +       .show = t_show,
> +       .stop = t_stop,
> +};
> +
> +static int
> +ftrace_formats_open(struct inode *inode, struct file *file)
> +{
> +       int ret;
> +
> +       ret = security_locked_down(LOCKDOWN_TRACEFS);
> +       if (ret)
> +               return ret;
> +
> +       return seq_open(file, &show_format_seq_ops);
> +}
> +
> +static const struct file_operations ftrace_formats_fops = {
> +       .open = ftrace_formats_open,
> +       .read = seq_read,
> +       .llseek = seq_lseek,
> +       .release = seq_release,
> +};
> +
> +static __init int init_trace_printk_function_export(void)
> +{
> +       int ret;
> +
> +       ret = tracing_init_dentry();
> +       if (ret)
> +               return 0;
> +
> +       trace_create_file("printk_formats", TRACE_MODE_READ, NULL,
> +                                   NULL, &ftrace_formats_fops);
> +
> +       return 0;
> +}
> +
> +fs_initcall(init_trace_printk_function_export);
> +
> +static __init int init_trace_printk(void)
> +{
> +       return register_module_notifier(&module_trace_bprintk_format_nb);
> +}
> +
> +early_initcall(init_trace_printk);
> --
> 2.50.1.windows.1
> 
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-09-09 10:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-06 13:41 [PATCH] tracing: Fix multiple issues in trace_printk module handling Fidal Palamparambil
2025-09-07  1:23 ` Luis Chamberlain
2025-09-07  1:56 ` kernel test robot
2025-09-07  4:11 ` kernel test robot
2025-09-07  7:17 ` kernel test robot
2025-09-09  9:46 ` Christophe Leroy
  -- strict thread matches above, loose matches on Subject: below --
2025-09-07 13:52 [PATCH] tracing : " Fidal Palamparambil
2025-09-07 19:10 ` Luis Chamberlain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).