Message ID | 20200822014018.913868-2-lokeshgidra@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Control over userfaultfd kernel-fault handling | expand |
On 2020-08-21 18:40:17 [-0700], Lokesh Gidra wrote: > --- a/fs/userfaultfd.c > +++ b/fs/userfaultfd.c > @@ -1966,6 +1969,7 @@ static void init_once_userfaultfd_ctx(void *mem) > > SYSCALL_DEFINE1(userfaultfd, int, flags) > { > + static const int uffd_flags = UFFD_USER_MODE_ONLY; > struct userfaultfd_ctx *ctx; > int fd; Why? Sebastian
On Mon, Aug 24, 2020 at 5:32 AM Sebastian Andrzej Siewior <bigeasy@linutronix.de> wrote: > > On 2020-08-21 18:40:17 [-0700], Lokesh Gidra wrote: > > --- a/fs/userfaultfd.c > > +++ b/fs/userfaultfd.c > > @@ -1966,6 +1969,7 @@ static void init_once_userfaultfd_ctx(void *mem) > > > > SYSCALL_DEFINE1(userfaultfd, int, flags) > > { > > + static const int uffd_flags = UFFD_USER_MODE_ONLY; > > struct userfaultfd_ctx *ctx; > > int fd; > Why? Not sure! I guess Daniel didn't want to repeat the long flag name twice. Thanks for catching that. I'll send another version fixing this. > > Sebastian
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 0e4a3837da52..3e4ae6145112 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -405,6 +405,9 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason) if (ctx->features & UFFD_FEATURE_SIGBUS) goto out; + if ((vmf->flags & FAULT_FLAG_USER) == 0 && + ctx->flags & UFFD_USER_MODE_ONLY) + goto out; /* * If it's already released don't get it. This avoids to loop @@ -1966,6 +1969,7 @@ static void init_once_userfaultfd_ctx(void *mem) SYSCALL_DEFINE1(userfaultfd, int, flags) { + static const int uffd_flags = UFFD_USER_MODE_ONLY; struct userfaultfd_ctx *ctx; int fd; @@ -1975,10 +1979,11 @@ SYSCALL_DEFINE1(userfaultfd, int, flags) BUG_ON(!current->mm); /* Check the UFFD_* constants for consistency. */ + BUILD_BUG_ON(uffd_flags & UFFD_SHARED_FCNTL_FLAGS); BUILD_BUG_ON(UFFD_CLOEXEC != O_CLOEXEC); BUILD_BUG_ON(UFFD_NONBLOCK != O_NONBLOCK); - if (flags & ~UFFD_SHARED_FCNTL_FLAGS) + if (flags & ~(UFFD_SHARED_FCNTL_FLAGS | uffd_flags)) return -EINVAL; ctx = kmem_cache_alloc(userfaultfd_ctx_cachep, GFP_KERNEL); diff --git a/include/uapi/linux/userfaultfd.h b/include/uapi/linux/userfaultfd.h index e7e98bde221f..5f2d88212f7c 100644 --- a/include/uapi/linux/userfaultfd.h +++ b/include/uapi/linux/userfaultfd.h @@ -257,4 +257,13 @@ struct uffdio_writeprotect { __u64 mode; }; +/* + * Flags for the userfaultfd(2) system call itself. + */ + +/* + * Create a userfaultfd that can handle page faults only in user mode. + */ +#define UFFD_USER_MODE_ONLY 1 + #endif /* _LINUX_USERFAULTFD_H */