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-fixes-v5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull seccomp fixes from Kees Cook:
"This fixes a hard-to-hit race condition in the addfd user_notif
feature of seccomp, visible since v5.9.

And a small documentation fix"

* tag 'seccomp-fixes-v5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
seccomp: Refactor notification handler to prepare for new semantics
Documentation: seccomp: Fix user notification documentation

+24 -22
+8 -8
Documentation/userspace-api/seccomp_filter.rst
··· 250 250 seccomp notification fd to receive a ``struct seccomp_notif``, which contains 251 251 five members: the input length of the structure, a unique-per-filter ``id``, 252 252 the ``pid`` of the task which triggered this request (which may be 0 if the 253 - task is in a pid ns not visible from the listener's pid namespace), a ``flags`` 254 - member which for now only has ``SECCOMP_NOTIF_FLAG_SIGNALED``, representing 255 - whether or not the notification is a result of a non-fatal signal, and the 256 - ``data`` passed to seccomp. Userspace can then make a decision based on this 257 - information about what to do, and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a 258 - response, indicating what should be returned to userspace. The ``id`` member of 259 - ``struct seccomp_notif_resp`` should be the same ``id`` as in ``struct 260 - seccomp_notif``. 253 + task is in a pid ns not visible from the listener's pid namespace). The 254 + notification also contains the ``data`` passed to seccomp, and a filters flag. 255 + The structure should be zeroed out prior to calling the ioctl. 256 + 257 + Userspace can then make a decision based on this information about what to do, 258 + and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a response, indicating what should be 259 + returned to userspace. The ``id`` member of ``struct seccomp_notif_resp`` should 260 + be the same ``id`` as in ``struct seccomp_notif``. 261 261 262 262 It is worth noting that ``struct seccomp_data`` contains the values of register 263 263 arguments to the syscall, but does not contain pointers to memory. The task's
+16 -14
kernel/seccomp.c
··· 1105 1105 1106 1106 up(&match->notif->request); 1107 1107 wake_up_poll(&match->wqh, EPOLLIN | EPOLLRDNORM); 1108 - mutex_unlock(&match->notify_lock); 1109 1108 1110 1109 /* 1111 1110 * This is where we wait for a reply from userspace. 1112 1111 */ 1113 - wait: 1114 - err = wait_for_completion_interruptible(&n.ready); 1115 - mutex_lock(&match->notify_lock); 1116 - if (err == 0) { 1117 - /* Check if we were woken up by a addfd message */ 1112 + do { 1113 + mutex_unlock(&match->notify_lock); 1114 + err = wait_for_completion_interruptible(&n.ready); 1115 + mutex_lock(&match->notify_lock); 1116 + if (err != 0) 1117 + goto interrupted; 1118 + 1118 1119 addfd = list_first_entry_or_null(&n.addfd, 1119 1120 struct seccomp_kaddfd, list); 1120 - if (addfd && n.state != SECCOMP_NOTIFY_REPLIED) { 1121 + /* Check if we were woken up by a addfd message */ 1122 + if (addfd) 1121 1123 seccomp_handle_addfd(addfd); 1122 - mutex_unlock(&match->notify_lock); 1123 - goto wait; 1124 - } 1125 - ret = n.val; 1126 - err = n.error; 1127 - flags = n.flags; 1128 - } 1129 1124 1125 + } while (n.state != SECCOMP_NOTIFY_REPLIED); 1126 + 1127 + ret = n.val; 1128 + err = n.error; 1129 + flags = n.flags; 1130 + 1131 + interrupted: 1130 1132 /* If there were any pending addfd calls, clear them out */ 1131 1133 list_for_each_entry_safe(addfd, tmp, &n.addfd, list) { 1132 1134 /* The process went away before we got a chance to handle it */