Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'seccomp-v5.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull seccomp fixes from Kees Cook:
"Syzbot found a use-after-free bug in seccomp due to flags that should
not be allowed to be used together.

Tycho fixed this, I updated the self-tests, and the syzkaller PoC has
been running for several days without triggering KASan (before this
fix, it would reproduce). These patches have also been in -next for
almost a week, just to be sure.

- Add logic for making some seccomp flags exclusive (Tycho)

- Update selftests for exclusivity testing (Kees)"

* tag 'seccomp-v5.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
seccomp: Make NEW_LISTENER and TSYNC flags exclusive
selftests/seccomp: Prepare for exclusive seccomp flags

+40 -11
+15 -2
kernel/seccomp.c
··· 502 502 * 503 503 * Caller must be holding current->sighand->siglock lock. 504 504 * 505 - * Returns 0 on success, -ve on error. 505 + * Returns 0 on success, -ve on error, or 506 + * - in TSYNC mode: the pid of a thread which was either not in the correct 507 + * seccomp mode or did not have an ancestral seccomp filter 508 + * - in NEW_LISTENER mode: the fd of the new listener 506 509 */ 507 510 static long seccomp_attach_filter(unsigned int flags, 508 511 struct seccomp_filter *filter) ··· 1261 1258 if (flags & ~SECCOMP_FILTER_FLAG_MASK) 1262 1259 return -EINVAL; 1263 1260 1261 + /* 1262 + * In the successful case, NEW_LISTENER returns the new listener fd. 1263 + * But in the failure case, TSYNC returns the thread that died. If you 1264 + * combine these two flags, there's no way to tell whether something 1265 + * succeeded or failed. So, let's disallow this combination. 1266 + */ 1267 + if ((flags & SECCOMP_FILTER_FLAG_TSYNC) && 1268 + (flags & SECCOMP_FILTER_FLAG_NEW_LISTENER)) 1269 + return -EINVAL; 1270 + 1264 1271 /* Prepare the new filter before holding any locks. */ 1265 1272 prepared = seccomp_prepare_user_filter(filter); 1266 1273 if (IS_ERR(prepared)) ··· 1317 1304 mutex_unlock(&current->signal->cred_guard_mutex); 1318 1305 out_put_fd: 1319 1306 if (flags & SECCOMP_FILTER_FLAG_NEW_LISTENER) { 1320 - if (ret < 0) { 1307 + if (ret) { 1321 1308 listener_f->private_data = NULL; 1322 1309 fput(listener_f); 1323 1310 put_unused_fd(listener);
+25 -9
tools/testing/selftests/seccomp/seccomp_bpf.c
··· 2166 2166 SECCOMP_FILTER_FLAG_LOG, 2167 2167 SECCOMP_FILTER_FLAG_SPEC_ALLOW, 2168 2168 SECCOMP_FILTER_FLAG_NEW_LISTENER }; 2169 - unsigned int flag, all_flags; 2169 + unsigned int exclusive[] = { 2170 + SECCOMP_FILTER_FLAG_TSYNC, 2171 + SECCOMP_FILTER_FLAG_NEW_LISTENER }; 2172 + unsigned int flag, all_flags, exclusive_mask; 2170 2173 int i; 2171 2174 long ret; 2172 2175 2173 - /* Test detection of known-good filter flags */ 2176 + /* Test detection of individual known-good filter flags */ 2174 2177 for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) { 2175 2178 int bits = 0; 2176 2179 ··· 2200 2197 all_flags |= flag; 2201 2198 } 2202 2199 2203 - /* Test detection of all known-good filter flags */ 2204 - ret = seccomp(SECCOMP_SET_MODE_FILTER, all_flags, NULL); 2205 - EXPECT_EQ(-1, ret); 2206 - EXPECT_EQ(EFAULT, errno) { 2207 - TH_LOG("Failed to detect that all known-good filter flags (0x%X) are supported!", 2208 - all_flags); 2200 + /* 2201 + * Test detection of all known-good filter flags combined. But 2202 + * for the exclusive flags we need to mask them out and try them 2203 + * individually for the "all flags" testing. 2204 + */ 2205 + exclusive_mask = 0; 2206 + for (i = 0; i < ARRAY_SIZE(exclusive); i++) 2207 + exclusive_mask |= exclusive[i]; 2208 + for (i = 0; i < ARRAY_SIZE(exclusive); i++) { 2209 + flag = all_flags & ~exclusive_mask; 2210 + flag |= exclusive[i]; 2211 + 2212 + ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); 2213 + EXPECT_EQ(-1, ret); 2214 + EXPECT_EQ(EFAULT, errno) { 2215 + TH_LOG("Failed to detect that all known-good filter flags (0x%X) are supported!", 2216 + flag); 2217 + } 2209 2218 } 2210 2219 2211 - /* Test detection of an unknown filter flag */ 2220 + /* Test detection of an unknown filter flags, without exclusives. */ 2212 2221 flag = -1; 2222 + flag &= ~exclusive_mask; 2213 2223 ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); 2214 2224 EXPECT_EQ(-1, ret); 2215 2225 EXPECT_EQ(EINVAL, errno) {