Skip to content

Commit

Permalink
Improve seccomp disable && Add locking to protect cred modifications …
Browse files Browse the repository at this point in the history
…in escape_to_root (#2320)

- When disabling Seccomp, ensure that current->sighand->siglock is held
during the operation.
- Locking to ensure safe access and modification of the `cred` structure
within the `escape_to_root` function.

---

I think this issue described in #2236 may have been caused by concurrent
read-write access without proper locking.

---------

Signed-off-by: SsageParuders<[email protected]>
Signed-off-by: SsageParuders <[email protected]>"
  • Loading branch information
SsageParuders authored Dec 28, 2024
1 parent 946391d commit 58ed786
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions kernel/core_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,38 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
set_groups(cred, group_info);
}

static void disable_seccomp()
{
assert_spin_locked(&current->sighand->siglock);
// disable seccomp
#if defined(CONFIG_GENERIC_ENTRY) && \
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP;
#else
current_thread_info()->flags &= ~(TIF_SECCOMP | _TIF_SECCOMP);
#endif

#ifdef CONFIG_SECCOMP
current->seccomp.mode = 0;
current->seccomp.filter = NULL;
#else
#endif
}

void escape_to_root(void)
{
struct cred *cred;

cred = (struct cred *)__task_cred(current);
rcu_read_lock();

do {
cred = (struct cred *)__task_cred((current));
BUG_ON(!cred);
} while (!get_cred_rcu(cred));

if (cred->euid.val == 0) {
pr_warn("Already root, don't escape!\n");
rcu_read_unlock();
return;
}
struct root_profile *profile = ksu_get_root_profile(cred->uid.val);
Expand Down Expand Up @@ -147,21 +171,15 @@ void escape_to_root(void)
memcpy(&cred->cap_ambient, &profile->capabilities.effective,
sizeof(cred->cap_ambient));

// disable seccomp
#if defined(CONFIG_GENERIC_ENTRY) && \
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP;
#else
current_thread_info()->flags &= ~(TIF_SECCOMP | _TIF_SECCOMP);
#endif
setup_groups(profile, cred);

#ifdef CONFIG_SECCOMP
current->seccomp.mode = 0;
current->seccomp.filter = NULL;
#else
#endif
rcu_read_unlock();

setup_groups(profile, cred);
// Refer to kernel/seccomp.c: seccomp_set_mode_strict
// When disabling Seccomp, ensure that current->sighand->siglock is held during the operation.
spin_lock_irq(&current->sighand->siglock);
disable_seccomp();
spin_unlock_irq(&current->sighand->siglock);

setup_selinux(profile->selinux_domain);
}
Expand Down

0 comments on commit 58ed786

Please sign in to comment.