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

 - Check kprobe is enabled before unregistering from ftrace as it isn't
   registered when disabled.

 - Remove kprobes enabled via command-line that is on init text when
   freed.

 - Add missing RCU synchronization for ftrace trampoline symbols removed
   from kallsyms.

 - Free trampoline on error path if ftrace_startup() fails.

 - Give more space for the longer PID numbers in trace output.

 - Fix a possible double free in the histogram code.

 - A couple of fixes that were discovered by sparse.

* tag 'trace-v5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  bootconfig: init: make xbc_namebuf static
  kprobes: tracing/kprobes: Fix to kill kprobes on initmem after boot
  tracing: fix double free
  ftrace: Let ftrace_enable_sysctl take a kernel pointer buffer
  tracing: Make the space reserved for the pid wider
  ftrace: Fix missing synchronize_rcu() removing trampoline from kallsyms
  ftrace: Free the trampoline when ftrace_startup() fails
  kprobes: Fix to check probe enabled before disarm_kprobe_ftrace()
parents 98477740 a27026e9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -373,6 +373,8 @@ void unregister_kretprobes(struct kretprobe **rps, int num);
void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);

void kprobe_free_init_mem(void);

int disable_kprobe(struct kprobe *kp);
int enable_kprobe(struct kprobe *kp);

@@ -435,6 +437,9 @@ static inline void unregister_kretprobes(struct kretprobe **rps, int num)
static inline void kprobe_flush_task(struct task_struct *tk)
{
}
static inline void kprobe_free_init_mem(void)
{
}
static inline int disable_kprobe(struct kprobe *kp)
{
	return -ENOSYS;
+3 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <linux/nmi.h>
#include <linux/percpu.h>
#include <linux/kmod.h>
#include <linux/kprobes.h>
#include <linux/vmalloc.h>
#include <linux/kernel_stat.h>
#include <linux/start_kernel.h>
@@ -303,7 +304,7 @@ static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)

#ifdef CONFIG_BOOT_CONFIG

char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;
static char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;

#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)

@@ -1402,6 +1403,7 @@ static int __ref kernel_init(void *unused)
	kernel_init_freeable();
	/* need to finish all async __init code before freeing the memory */
	async_synchronize_full();
	kprobe_free_init_mem();
	ftrace_free_init_mem();
	free_initmem();
	mark_readonly();
+25 −2
Original line number Diff line number Diff line
@@ -2162,9 +2162,10 @@ static void kill_kprobe(struct kprobe *p)

	/*
	 * The module is going away. We should disarm the kprobe which
	 * is using ftrace.
	 * is using ftrace, because ftrace framework is still available at
	 * MODULE_STATE_GOING notification.
	 */
	if (kprobe_ftrace(p))
	if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
		disarm_kprobe_ftrace(p);
}

@@ -2459,6 +2460,28 @@ static struct notifier_block kprobe_module_nb = {
extern unsigned long __start_kprobe_blacklist[];
extern unsigned long __stop_kprobe_blacklist[];

void kprobe_free_init_mem(void)
{
	void *start = (void *)(&__init_begin);
	void *end = (void *)(&__init_end);
	struct hlist_head *head;
	struct kprobe *p;
	int i;

	mutex_lock(&kprobe_mutex);

	/* Kill all kprobes on initmem */
	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
		head = &kprobe_table[i];
		hlist_for_each_entry(p, head, hlist) {
			if (start <= (void *)p->addr && (void *)p->addr < end)
				kill_kprobe(p);
		}
	}

	mutex_unlock(&kprobe_mutex);
}

static int __init init_kprobes(void)
{
	int i, err = 0;
+3 −0
Original line number Diff line number Diff line
@@ -2782,6 +2782,7 @@ static void ftrace_remove_trampoline_from_kallsyms(struct ftrace_ops *ops)
{
	lockdep_assert_held(&ftrace_lock);
	list_del_rcu(&ops->list);
	synchronize_rcu();
}

/*
@@ -2862,6 +2863,8 @@ int ftrace_startup(struct ftrace_ops *ops, int command)
		__unregister_ftrace_function(ops);
		ftrace_start_up--;
		ops->flags &= ~FTRACE_OPS_FL_ENABLED;
		if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
			ftrace_trampoline_free(ops);
		return ret;
	}

+19 −19
Original line number Diff line number Diff line
@@ -3819,7 +3819,7 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file
{
	bool tgid = flags & TRACE_ITER_RECORD_TGID;
	const char *space = "            ";
	int prec = tgid ? 10 : 2;
	int prec = tgid ? 12 : 2;

	print_event_info(buf, m);

Loading