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

userfaultfd: open userfaultfds with O_RDONLY

Since userfaultfd doesn't implement a write operation, it is more
appropriate to open it read-only.

When userfaultfds are opened read-write like it is now, and such fd is
passed from one process to another, SELinux will check both read and
write permissions for the target process, even though it can't actually
do any write operation on the fd later.

Inspired by the following bug report, which has hit the SELinux scenario
described above:
https://bugzilla.redhat.com/show_bug.cgi?id=1974559

Reported-by: Robert O'Callahan <roc@ocallahan.org>
Fixes: 86039bd3b4e6 ("userfaultfd: add new syscall to provide memory externalization")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
Acked-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Ondrej Mosnacek and committed by
Paul Moore
abec3d01 ed5d44d4

+2 -2
+2 -2
fs/userfaultfd.c
··· 991 991 int fd; 992 992 993 993 fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, new, 994 - O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode); 994 + O_RDONLY | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode); 995 995 if (fd < 0) 996 996 return fd; 997 997 ··· 2090 2090 mmgrab(ctx->mm); 2091 2091 2092 2092 fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, ctx, 2093 - O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL); 2093 + O_RDONLY | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL); 2094 2094 if (fd < 0) { 2095 2095 mmdrop(ctx->mm); 2096 2096 kmem_cache_free(userfaultfd_ctx_cachep, ctx);