Skip to content

Commit 58ed786

Browse files
Improve seccomp disable && Add locking to protect cred modifications in escape_to_root (tiann#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 tiann#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]>"
1 parent 946391d commit 58ed786

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

kernel/core_hook.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,38 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
106106
set_groups(cred, group_info);
107107
}
108108

109+
static void disable_seccomp()
110+
{
111+
assert_spin_locked(&current->sighand->siglock);
112+
// disable seccomp
113+
#if defined(CONFIG_GENERIC_ENTRY) && \
114+
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
115+
current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP;
116+
#else
117+
current_thread_info()->flags &= ~(TIF_SECCOMP | _TIF_SECCOMP);
118+
#endif
119+
120+
#ifdef CONFIG_SECCOMP
121+
current->seccomp.mode = 0;
122+
current->seccomp.filter = NULL;
123+
#else
124+
#endif
125+
}
126+
109127
void escape_to_root(void)
110128
{
111129
struct cred *cred;
112130

113-
cred = (struct cred *)__task_cred(current);
131+
rcu_read_lock();
132+
133+
do {
134+
cred = (struct cred *)__task_cred((current));
135+
BUG_ON(!cred);
136+
} while (!get_cred_rcu(cred));
114137

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

150-
// disable seccomp
151-
#if defined(CONFIG_GENERIC_ENTRY) && \
152-
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
153-
current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP;
154-
#else
155-
current_thread_info()->flags &= ~(TIF_SECCOMP | _TIF_SECCOMP);
156-
#endif
174+
setup_groups(profile, cred);
157175

158-
#ifdef CONFIG_SECCOMP
159-
current->seccomp.mode = 0;
160-
current->seccomp.filter = NULL;
161-
#else
162-
#endif
176+
rcu_read_unlock();
163177

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

166184
setup_selinux(profile->selinux_domain);
167185
}

0 commit comments

Comments
 (0)