Skip to content

Commit 3893301

Browse files
SsageParudersrsuntk
authored andcommitted
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 96f93bf commit 3893301

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
@@ -110,14 +110,38 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
110110
set_groups(cred, group_info);
111111
}
112112

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

117-
cred = (struct cred *)__task_cred(current);
135+
rcu_read_lock();
136+
137+
do {
138+
cred = (struct cred *)__task_cred((current));
139+
BUG_ON(!cred);
140+
} while (!get_cred_rcu(cred));
118141

119142
if (cred->euid.val == 0) {
120143
pr_warn("Already root, don't escape!\n");
144+
rcu_read_unlock();
121145
return;
122146
}
123147
struct root_profile *profile = ksu_get_root_profile(cred->uid.val);
@@ -151,21 +175,15 @@ void escape_to_root(void)
151175
memcpy(&cred->cap_ambient, &profile->capabilities.effective,
152176
sizeof(cred->cap_ambient));
153177

154-
// disable seccomp
155-
#if defined(CONFIG_GENERIC_ENTRY) && \
156-
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
157-
current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP;
158-
#else
159-
current_thread_info()->flags &= ~(TIF_SECCOMP | _TIF_SECCOMP);
160-
#endif
178+
setup_groups(profile, cred);
161179

162-
#ifdef CONFIG_SECCOMP
163-
current->seccomp.mode = 0;
164-
current->seccomp.filter = NULL;
165-
#else
166-
#endif
180+
rcu_read_unlock();
167181

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

170188
setup_selinux(profile->selinux_domain);
171189
}

0 commit comments

Comments
 (0)