summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Rees <maxcrees@me.com>2020-12-14 14:53:23 -0500
committerPaul Moore <paul@paul-moore.com>2021-03-05 18:52:15 -0500
commit83d7b022fa7ef8c24516cc668efc879e5398403f (patch)
treeef0457d7fb1b0f5233fadba7412e2c09ed971c5c
parent6d5a0bb22c8162c167900a47d57ebdeeb22ff8c0 (diff)
downloadlibseccomp-83d7b022fa7ef8c24516cc668efc879e5398403f.tar.gz
system: use old SECCOMP_IOCTL_NOTIF_ID_VALID number if necessary
Kernel commit 47e33c05f9f0 ("seccomp: Fix ioctl number for SECCOMP_IOCTL_NOTIF_ID_VALID") changed the public definition of SECCOMP_IOCTL_NOTIF_ID_VALID for correctness sake because it had the wrong direction (no current functional change). If libseccomp is built against kernel headers after this commit but is run on a kernel that was built prior to this commit, then the ioctl will always return -1 EINVAL and thus seccomp_notify_id_valid will incorrectly return -ENOENT. Copy the (now non-public) definition of the old ioctl number and try it if the ioctl with the number from the kernel headers fails with -1 EINVAL. Also, update the fallback definition of SECCOMP_IOCTL_NOTIF_ID_VALID to the new value. Acked-by: Tom Hromatka <tom.hromatka@oracle.com> Signed-off-by: Max Rees <maxcrees@me.com> [PM: tweak some vertical whitespace, subject line] Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r--src/system.c12
-rw-r--r--src/system.h5
2 files changed, 15 insertions, 2 deletions
diff --git a/src/system.c b/src/system.c
index c646c65..ae445bf 100644
--- a/src/system.c
+++ b/src/system.c
@@ -535,10 +535,20 @@ int sys_notify_respond(int fd, struct seccomp_notif_resp *resp)
*/
int sys_notify_id_valid(int fd, uint64_t id)
{
+ int rc;
if (state.sup_user_notif <= 0)
return -EOPNOTSUPP;
- if (ioctl(fd, SECCOMP_IOCTL_NOTIF_ID_VALID, &id) < 0)
+ rc = ioctl(fd, SECCOMP_IOCTL_NOTIF_ID_VALID, &id);
+ if (rc < 0 && errno == EINVAL)
+ /* It is possible that libseccomp was built against newer kernel
+ * headers than the kernel it is running on. If so, the older
+ * runtime kernel may not support the "fixed"
+ * SECCOMP_IOCTL_NOTIF_ID_VALID ioctl number which was introduced in
+ * kernel commit 47e33c05f9f0 ("seccomp: Fix ioctl number for
+ * SECCOMP_IOCTL_NOTIF_ID_VALID"). Try the old value. */
+ rc = ioctl(fd, SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR, &id);
+ if (rc < 0)
return -ENOENT;
return 0;
}
diff --git a/src/system.h b/src/system.h
index b8c2bc9..490f00f 100644
--- a/src/system.h
+++ b/src/system.h
@@ -179,9 +179,12 @@ struct seccomp_notif_resp {
#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif)
#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, \
struct seccomp_notif_resp)
-#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOR(2, __u64)
+#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64)
#endif /* SECCOMP_RET_USER_NOTIF */
+/* non-public ioctl number for backwards compat (see system.c) */
+#define SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR SECCOMP_IOR(2, __u64)
+
void sys_reset_state(void);
int sys_chk_seccomp_syscall(void);