]> Git Repo - linux.git/commit
userfaultfd: non-cooperative: fix fork use after free
authorAndrea Arcangeli <[email protected]>
Tue, 3 Oct 2017 23:15:38 +0000 (16:15 -0700)
committerLinus Torvalds <[email protected]>
Wed, 4 Oct 2017 00:54:25 +0000 (17:54 -0700)
commit384632e67e0829deb8015ee6ad916b180049d252
tree24dbfe0561ac449ff84af9a6ca598b29f7d95bd4
parent7d790d2da386a52cfebcf0c898ba927bece9d4ab
userfaultfd: non-cooperative: fix fork use after free

When reading the event from the uffd, we put it on a temporary
fork_event list to detect if we can still access it after releasing and
retaking the event_wqh.lock.

If fork aborts and removes the event from the fork_event all is fine as
long as we're still in the userfault read context and fork_event head is
still alive.

We've to put the event allocated in the fork kernel stack, back from
fork_event list-head to the event_wqh head, before returning from
userfaultfd_ctx_read, because the fork_event head lifetime is limited to
the userfaultfd_ctx_read stack lifetime.

Forgetting to move the event back to its event_wqh place then results in
__remove_wait_queue(&ctx->event_wqh, &ewq->wq); in
userfaultfd_event_wait_completion to remove it from a head that has been
already freed from the reader stack.

This could only happen if resolve_userfault_fork failed (for example if
there are no file descriptors available to allocate the fork uffd).  If
it succeeded it was put back correctly.

Furthermore, after find_userfault_evt receives a fork event, the forked
userfault context in fork_nctx and uwq->msg.arg.reserved.reserved1 can
be released by the fork thread as soon as the event_wqh.lock is
released.  Taking a reference on the fork_nctx before dropping the lock
prevents an use after free in resolve_userfault_fork().

If the fork side aborted and it already released everything, we still
try to succeed resolve_userfault_fork(), if possible.

Fixes: 893e26e61d04eac9 ("userfaultfd: non-cooperative: Add fork() event")
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Andrea Arcangeli <[email protected]>
Reported-by: Mark Rutland <[email protected]>
Tested-by: Mark Rutland <[email protected]>
Cc: Pavel Emelyanov <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: "Dr. David Alan Gilbert" <[email protected]>
Cc: Mike Kravetz <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
fs/userfaultfd.c
This page took 0.056486 seconds and 4 git commands to generate.