Skip to content

Commit 3d73f89

Browse files
authored
kernel: Allocate fake struct on heap (#3081)
task_struct is typically 4000+ bytes long.
1 parent 5ab71b4 commit 3d73f89

1 file changed

Lines changed: 15 additions & 5 deletions

File tree

kernel/app_profile.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <linux/sched.h>
44
#include <linux/sched/signal.h>
55
#include <linux/seccomp.h>
6+
#include <linux/slab.h>
67
#include <linux/thread_info.h>
78
#include <linux/uidgid.h>
89
#include <linux/version.h>
@@ -63,7 +64,14 @@ void seccomp_filter_release(struct task_struct *tsk);
6364

6465
static void disable_seccomp(void)
6566
{
66-
struct task_struct fake;
67+
struct task_struct *fake;
68+
69+
fake = kmalloc(sizeof(*fake), GFP_ATOMIC);
70+
if (!fake) {
71+
pr_warn("failed to alloc fake task_struct\n");
72+
return;
73+
}
74+
6775
// Refer to kernel/seccomp.c: seccomp_set_mode_strict
6876
// When disabling Seccomp, ensure that current->sighand->siglock is held during the operation.
6977
spin_lock_irq(&current->sighand->siglock);
@@ -75,21 +83,23 @@ static void disable_seccomp(void)
7583
clear_thread_flag(TIF_SECCOMP);
7684
#endif
7785

78-
memcpy(&fake, current, sizeof(fake));
86+
memcpy(fake, current, sizeof(*fake));
87+
7988
current->seccomp.mode = 0;
8089
current->seccomp.filter = NULL;
8190
atomic_set(&current->seccomp.filter_count, 0);
8291
spin_unlock_irq(&current->sighand->siglock);
8392

8493
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
8594
// https://github.com/torvalds/linux/commit/bfafe5efa9754ebc991750da0bcca2a6694f3ed3#diff-45eb79a57536d8eccfc1436932f093eb5c0b60d9361c39edb46581ad313e8987R576-R577
86-
fake.flags |= PF_EXITING;
95+
fake->flags |= PF_EXITING;
8796
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
8897
// https://github.com/torvalds/linux/commit/0d8315dddd2899f519fe1ca3d4d5cdaf44ea421e#diff-45eb79a57536d8eccfc1436932f093eb5c0b60d9361c39edb46581ad313e8987R556-R558
89-
fake.sighand = NULL;
98+
fake->sighand = NULL;
9099
#endif
91100

92-
seccomp_filter_release(&fake);
101+
seccomp_filter_release(fake);
102+
kfree(fake);
93103
}
94104

95105
void escape_with_root_profile(void)

0 commit comments

Comments
 (0)