Skip to content

Commit

Permalink
kprobes: tracing/kprobes: Fix to kill kprobes on initmem after boot
Browse files Browse the repository at this point in the history
Since kprobe_event= cmdline option allows user to put kprobes on the
functions in initmem, kprobe has to make such probes gone after boot.
Currently the probes on the init functions in modules will be handled
by module callback, but the kernel init text isn't handled.
Without this, kprobes may access non-exist text area to disable or
remove it.

Link: https://lkml.kernel.org/r/159972810544.428528.1839307531600646955.stgit@devnote2

Fixes: 970988e ("tracing/kprobe: Add kprobe_event= boot parameter")
Cc: Jonathan Corbet <[email protected]>
Cc: Shuah Khan <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: [email protected]
Signed-off-by: Masami Hiramatsu <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
  • Loading branch information
mhiramat authored and rostedt committed Sep 18, 2020
1 parent 46bbe5c commit 82d083a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/linux/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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();
Expand Down
22 changes: 22 additions & 0 deletions kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2453,6 +2453,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;
Expand Down

0 comments on commit 82d083a

Please sign in to comment.