userfaultfd: non-cooperative: fix fork fctx->new memleak
authorMike Rapoport <rppt@linux.vnet.ibm.com>
Fri, 10 Mar 2017 00:17:09 +0000 (16:17 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Mar 2017 01:01:10 +0000 (17:01 -0800)
We have a memleak in the ->new ctx if the uffd of the parent is closed
before the fork event is read, nothing frees the new context.

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

index dd48052e086f6de4092abde32c36a86125e4584d..2407249998c326e178087f65eb1500954e32abf1 100644 (file)
@@ -549,6 +549,15 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx,
                if (ACCESS_ONCE(ctx->released) ||
                    fatal_signal_pending(current)) {
                        __remove_wait_queue(&ctx->event_wqh, &ewq->wq);
+                       if (ewq->msg.event == UFFD_EVENT_FORK) {
+                               struct userfaultfd_ctx *new;
+
+                               new = (struct userfaultfd_ctx *)
+                                       (unsigned long)
+                                       ewq->msg.arg.reserved.reserved1;
+
+                               userfaultfd_ctx_put(new);
+                       }
                        break;
                }