userfaultfd: non-cooperative: report all available features to userland
authorAndrea Arcangeli <aarcange@redhat.com>
Wed, 22 Feb 2017 23:42:24 +0000 (15:42 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Feb 2017 00:41:28 +0000 (16:41 -0800)
This will allow userland to probe all features available in the kernel.
It will however only enable the requested features in the open userfaultfd
context.

Link: http://lkml.kernel.org/r/20161216144821.5183-8-aarcange@redhat.com
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Hillf Danton <hillf.zj@alibaba-inc.com>
Cc: Michael Rapoport <RAPOPORT@il.ibm.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/userfaultfd.c

index b5074a34463517b3955151171a70ab19cfe34ffb..87d31921b66cdd3072a4f1beb74e05ce49ef3caf 100644 (file)
@@ -1285,6 +1285,7 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,
        struct uffdio_api uffdio_api;
        void __user *buf = (void __user *)arg;
        int ret;
+       __u64 features;
 
        ret = -EINVAL;
        if (ctx->state != UFFD_STATE_WAIT_API)
@@ -1292,21 +1293,23 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,
        ret = -EFAULT;
        if (copy_from_user(&uffdio_api, buf, sizeof(uffdio_api)))
                goto out;
-       if (uffdio_api.api != UFFD_API ||
-           (uffdio_api.features & ~UFFD_API_FEATURES)) {
+       features = uffdio_api.features;
+       if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES)) {
                memset(&uffdio_api, 0, sizeof(uffdio_api));
                if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api)))
                        goto out;
                ret = -EINVAL;
                goto out;
        }
-       uffdio_api.features &= UFFD_API_FEATURES;
+       /* report all available features and ioctls to userland */
+       uffdio_api.features = UFFD_API_FEATURES;
        uffdio_api.ioctls = UFFD_API_IOCTLS;
        ret = -EFAULT;
        if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api)))
                goto out;
        ctx->state = UFFD_STATE_RUNNING;
-       ctx->features = uffd_ctx_features(uffdio_api.features);
+       /* only enable the requested features for this uffd context */
+       ctx->features = uffd_ctx_features(features);
        ret = 0;
 out:
        return ret;