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

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

Pull seccomp fixes from Kees Cook:
"Fixes for seccomp_notify_ioctl uapi sanity from Sargun Dhillon.

The bulk of this is fixing the surrounding samples and selftests so
that seccomp can correctly validate the seccomp_notify_ioctl buffer as
being initially zeroed.

Summary:

- Fix samples and selftests to zero passed-in buffer

- Enforce zeroed buffer checking

- Verify buffer sanity check in selftest"

* tag 'seccomp-v5.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
selftests/seccomp: Catch garbage on SECCOMP_IOCTL_NOTIF_RECV
seccomp: Check that seccomp_notif is zeroed out by the user
selftests/seccomp: Zero out seccomp_notif
samples/seccomp: Zero out members based on seccomp_notif_sizes

+23 -3
+7
kernel/seccomp.c
··· 1026 1026 struct seccomp_notif unotif; 1027 1027 ssize_t ret; 1028 1028 1029 + /* Verify that we're not given garbage to keep struct extensible. */ 1030 + ret = check_zeroed_user(buf, sizeof(unotif)); 1031 + if (ret < 0) 1032 + return ret; 1033 + if (!ret) 1034 + return -EINVAL; 1035 + 1029 1036 memset(&unotif, 0, sizeof(unotif)); 1030 1037 1031 1038 ret = down_interruptible(&filter->notif->request);
+2 -2
samples/seccomp/user-trap.c
··· 298 298 req = malloc(sizes.seccomp_notif); 299 299 if (!req) 300 300 goto out_close; 301 - memset(req, 0, sizeof(*req)); 302 301 303 302 resp = malloc(sizes.seccomp_notif_resp); 304 303 if (!resp) 305 304 goto out_req; 306 - memset(resp, 0, sizeof(*resp)); 305 + memset(resp, 0, sizes.seccomp_notif_resp); 307 306 308 307 while (1) { 308 + memset(req, 0, sizes.seccomp_notif); 309 309 if (ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, req)) { 310 310 perror("ioctl recv"); 311 311 goto out_resp;
+14 -1
tools/testing/selftests/seccomp/seccomp_bpf.c
··· 3158 3158 EXPECT_GT(poll(&pollfd, 1, -1), 0); 3159 3159 EXPECT_EQ(pollfd.revents, POLLIN); 3160 3160 3161 - EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); 3161 + /* Test that we can't pass garbage to the kernel. */ 3162 + memset(&req, 0, sizeof(req)); 3163 + req.pid = -1; 3164 + errno = 0; 3165 + ret = ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req); 3166 + EXPECT_EQ(-1, ret); 3167 + EXPECT_EQ(EINVAL, errno); 3168 + 3169 + if (ret) { 3170 + req.pid = 0; 3171 + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); 3172 + } 3162 3173 3163 3174 pollfd.fd = listener; 3164 3175 pollfd.events = POLLIN | POLLOUT; ··· 3289 3278 3290 3279 close(sk_pair[1]); 3291 3280 3281 + memset(&req, 0, sizeof(req)); 3292 3282 EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); 3293 3283 3294 3284 EXPECT_EQ(kill(pid, SIGUSR1), 0); ··· 3308 3296 EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); 3309 3297 EXPECT_EQ(errno, ENOENT); 3310 3298 3299 + memset(&req, 0, sizeof(req)); 3311 3300 EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); 3312 3301 3313 3302 resp.id = req.id;