Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a71398c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tracing fixes from Steven Rostedt:

 - Out of range read of stack trace output

 - Fix for NULL pointer dereference in trace_uprobe_create()

 - Fix to a livepatching / ftrace permission race in the module code

 - Fix for NULL pointer dereference in free_ftrace_func_mapper()

 - A couple of build warning clean ups

* tag 'trace-v5.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  ftrace: Fix NULL pointer dereference in free_ftrace_func_mapper()
  module: Fix livepatch/ftrace module text permissions race
  tracing/uprobe: Fix obsolete comment on trace_uprobe_create()
  tracing/uprobe: Fix NULL pointer dereference in trace_uprobe_create()
  tracing: Make two symbols static
  tracing: avoid build warning with HAVE_NOP_MCOUNT
  tracing: Fix out-of-range read in trace_stack_print()
parents 0011572c 04e03d9a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/elf.h>
#include <linux/moduleloader.h>
#include <linux/completion.h>
#include <linux/memory.h>
#include <asm/cacheflush.h>
#include "core.h"
#include "patch.h"
@@ -718,16 +719,21 @@ static int klp_init_object_loaded(struct klp_patch *patch,
	struct klp_func *func;
	int ret;

	mutex_lock(&text_mutex);

	module_disable_ro(patch->mod);
	ret = klp_write_object_relocations(patch->mod, obj);
	if (ret) {
		module_enable_ro(patch->mod, true);
		mutex_unlock(&text_mutex);
		return ret;
	}

	arch_klp_init_object_loaded(patch, obj);
	module_enable_ro(patch->mod, true);

	mutex_unlock(&text_mutex);

	klp_for_each_func(obj, func) {
		ret = klp_find_object_symbol(obj->name, func->old_name,
					     func->old_sympos,
+16 −6
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <linux/hash.h>
#include <linux/rcupdate.h>
#include <linux/kprobes.h>
#include <linux/memory.h>

#include <trace/events/sched.h>

@@ -2610,10 +2611,12 @@ static void ftrace_run_update_code(int command)
{
	int ret;

	mutex_lock(&text_mutex);

	ret = ftrace_arch_code_modify_prepare();
	FTRACE_WARN_ON(ret);
	if (ret)
		return;
		goto out_unlock;

	/*
	 * By default we use stop_machine() to modify the code.
@@ -2625,6 +2628,9 @@ static void ftrace_run_update_code(int command)

	ret = ftrace_arch_code_modify_post_process();
	FTRACE_WARN_ON(ret);

out_unlock:
	mutex_unlock(&text_mutex);
}

static void ftrace_run_modify_code(struct ftrace_ops *ops, int command,
@@ -2935,14 +2941,13 @@ static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs)
			p = &pg->records[i];
			p->flags = rec_flags;

#ifndef CC_USING_NOP_MCOUNT
			/*
			 * Do the initial record conversion from mcount jump
			 * to the NOP instructions.
			 */
			if (!ftrace_code_disable(mod, p))
			if (!__is_defined(CC_USING_NOP_MCOUNT) &&
			    !ftrace_code_disable(mod, p))
				break;
#endif

			update_cnt++;
		}
@@ -4221,10 +4226,13 @@ void free_ftrace_func_mapper(struct ftrace_func_mapper *mapper,
	struct ftrace_func_entry *entry;
	struct ftrace_func_map *map;
	struct hlist_head *hhd;
	int size = 1 << mapper->hash.size_bits;
	int i;
	int size, i;

	if (!mapper)
		return;

	if (free_func && mapper->hash.count) {
		size = 1 << mapper->hash.size_bits;
		for (i = 0; i < size; i++) {
			hhd = &mapper->hash.buckets[i];
			hlist_for_each_entry(entry, hhd, hlist) {
@@ -5776,6 +5784,7 @@ void ftrace_module_enable(struct module *mod)
	struct ftrace_page *pg;

	mutex_lock(&ftrace_lock);
	mutex_lock(&text_mutex);

	if (ftrace_disabled)
		goto out_unlock;
@@ -5837,6 +5846,7 @@ void ftrace_module_enable(struct module *mod)
		ftrace_arch_code_modify_post_process();

 out_unlock:
	mutex_unlock(&text_mutex);
	mutex_unlock(&ftrace_lock);

	process_cached_mods(mod->name);
+2 −2
Original line number Diff line number Diff line
@@ -6923,7 +6923,7 @@ struct tracing_log_err {

static DEFINE_MUTEX(tracing_err_log_lock);

struct tracing_log_err *get_tracing_log_err(struct trace_array *tr)
static struct tracing_log_err *get_tracing_log_err(struct trace_array *tr)
{
	struct tracing_log_err *err;

@@ -8192,7 +8192,7 @@ static const struct file_operations buffer_percent_fops = {
	.llseek		= default_llseek,
};

struct dentry *trace_instance_dir;
static struct dentry *trace_instance_dir;

static void
init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer);
+1 −1
Original line number Diff line number Diff line
@@ -1057,7 +1057,7 @@ static enum print_line_t trace_stack_print(struct trace_iterator *iter,

	trace_seq_puts(s, "<stack trace>\n");

	for (p = field->caller; p && *p != ULONG_MAX && p < end; p++) {
	for (p = field->caller; p && p < end && *p != ULONG_MAX; p++) {

		if (trace_seq_has_overflowed(s))
			break;
+10 −5
Original line number Diff line number Diff line
@@ -426,8 +426,6 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
/*
 * Argument syntax:
 *  - Add uprobe: p|r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS]
 *
 *  - Remove uprobe: -:[GRP/]EVENT
 */
static int trace_uprobe_create(int argc, const char **argv)
{
@@ -443,10 +441,17 @@ static int trace_uprobe_create(int argc, const char **argv)
	ret = 0;
	ref_ctr_offset = 0;

	/* argc must be >= 1 */
	if (argv[0][0] == 'r')
	switch (argv[0][0]) {
	case 'r':
		is_return = true;
	else if (argv[0][0] != 'p' || argc < 2)
		break;
	case 'p':
		break;
	default:
		return -ECANCELED;
	}

	if (argc < 2)
		return -ECANCELED;

	if (argv[0][1] == ':')