diff options
author | Max Rees <maxcrees@me.com> | 2020-12-14 14:53:23 -0500 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2021-03-05 18:53:57 -0500 |
commit | b926e5af7295b04e8cf7ac4929731fed0f53a711 (patch) | |
tree | afa6e13448164542f69487d5c01bb71354f6f15f | |
parent | f679355a87d8e8ad5bc16d23e2a2e174a03a6f11 (diff) | |
download | libseccomp-b926e5af7295b04e8cf7ac4929731fed0f53a711.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>
(imported from commit 83d7b022fa7ef8c24516cc668efc879e5398403f)
-rw-r--r-- | src/system.c | 12 | ||||
-rw-r--r-- | src/system.h | 5 |
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 096f3ca..10d3ccb 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); |