Skip to content

Commit 82d083a

Browse files
mhiramatrostedt
authored andcommitted
kprobes: tracing/kprobes: Fix to kill kprobes on initmem after boot
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]>
1 parent 46bbe5c commit 82d083a

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

include/linux/kprobes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ void unregister_kretprobes(struct kretprobe **rps, int num);
373373
void kprobe_flush_task(struct task_struct *tk);
374374
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
375375

376+
void kprobe_free_init_mem(void);
377+
376378
int disable_kprobe(struct kprobe *kp);
377379
int enable_kprobe(struct kprobe *kp);
378380

@@ -435,6 +437,9 @@ static inline void unregister_kretprobes(struct kretprobe **rps, int num)
435437
static inline void kprobe_flush_task(struct task_struct *tk)
436438
{
437439
}
440+
static inline void kprobe_free_init_mem(void)
441+
{
442+
}
438443
static inline int disable_kprobe(struct kprobe *kp)
439444
{
440445
return -ENOSYS;

init/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <linux/nmi.h>
3434
#include <linux/percpu.h>
3535
#include <linux/kmod.h>
36+
#include <linux/kprobes.h>
3637
#include <linux/vmalloc.h>
3738
#include <linux/kernel_stat.h>
3839
#include <linux/start_kernel.h>
@@ -1402,6 +1403,7 @@ static int __ref kernel_init(void *unused)
14021403
kernel_init_freeable();
14031404
/* need to finish all async __init code before freeing the memory */
14041405
async_synchronize_full();
1406+
kprobe_free_init_mem();
14051407
ftrace_free_init_mem();
14061408
free_initmem();
14071409
mark_readonly();

kernel/kprobes.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,6 +2453,28 @@ static struct notifier_block kprobe_module_nb = {
24532453
extern unsigned long __start_kprobe_blacklist[];
24542454
extern unsigned long __stop_kprobe_blacklist[];
24552455

2456+
void kprobe_free_init_mem(void)
2457+
{
2458+
void *start = (void *)(&__init_begin);
2459+
void *end = (void *)(&__init_end);
2460+
struct hlist_head *head;
2461+
struct kprobe *p;
2462+
int i;
2463+
2464+
mutex_lock(&kprobe_mutex);
2465+
2466+
/* Kill all kprobes on initmem */
2467+
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
2468+
head = &kprobe_table[i];
2469+
hlist_for_each_entry(p, head, hlist) {
2470+
if (start <= (void *)p->addr && (void *)p->addr < end)
2471+
kill_kprobe(p);
2472+
}
2473+
}
2474+
2475+
mutex_unlock(&kprobe_mutex);
2476+
}
2477+
24562478
static int __init init_kprobes(void)
24572479
{
24582480
int i, err = 0;

0 commit comments

Comments
 (0)