Skip to content

Commit e53a694

Browse files
committed
ED: Fix potential task_struct double-frees when iterating over tasks
get_task_struct() is used on every task iterated upon in p_seccomp_entry() and p_iterate_processes() without a check to verify that the task_struct's refcount isn't already zero. It is therefore possible for LKRG to increment a dead task_struct's refcount from zero to one, thereby causing a double- free on the task_struct when the complementary put_task_struct() call takes place. Since the memory for a task_struct pointer obtained via one of the task list loop macros is protected via RCU, and RCU read lock protection already encapsulates LKRG's task iterations, the {get|put}_task_struct() calls are superfluous. Drop the {get|put}_task_struct() calls entirely to fix the potential double-free. This has the added bonus of speeding up the iteration because LKRG's iteration will never put a task_struct's last reference and get stuck doing task cleanup as a result. Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
1 parent a99a00b commit e53a694

File tree

2 files changed

+0
-5
lines changed

2 files changed

+0
-5
lines changed

src/modules/exploit_detection/p_exploit_detection.c

-3
Original file line numberDiff line numberDiff line change
@@ -1139,10 +1139,8 @@ static unsigned int p_iterate_processes(int (*p_func)(void *), char p_ver) {
11391139
do_each_thread(p_ptmp, p_tmp) {
11401140
#endif
11411141

1142-
get_task_struct(p_tmp);
11431142
/* do not touch kernel threads or the global init */
11441143
if (!p_is_ed_task(p_tmp)) {
1145-
put_task_struct(p_tmp);
11461144
continue;
11471145
}
11481146

@@ -1156,7 +1154,6 @@ static unsigned int p_iterate_processes(int (*p_func)(void *), char p_ver) {
11561154
}
11571155
}
11581156
}
1159-
put_task_struct(p_tmp);
11601157

11611158
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
11621159
}

src/modules/exploit_detection/syscalls/p_seccomp/p_seccomp.c

-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ int p_seccomp_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {
6767
rcu_read_lock();
6868
// Available since 3.14.0
6969
for_each_thread(p_father, p_threads) {
70-
get_task_struct(p_threads);
7170
p_child_tmp = p_find_ed_by_pid(task_pid_nr(p_threads));
7271
if (p_child_tmp) {
7372
#ifdef P_LKRG_TASK_OFF_DEBUG
@@ -80,7 +79,6 @@ int p_seccomp_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {
8079
p_child_tmp->p_ed_task.p_sec.flag_sync_thread = 1;
8180
p_set_ed_process_off(p_child_tmp);
8281
}
83-
put_task_struct(p_threads);
8482
}
8583
rcu_read_unlock();
8684
} else {

0 commit comments

Comments
 (0)