summaryrefslogtreecommitdiffstats
path: root/fs/binfmt_script.c
diff options
context:
space:
mode:
authorAndrea Arcangeli <aarcange@redhat.com>2017-10-03 16:15:38 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-10-03 17:54:25 -0700
commit384632e67e0829deb8015ee6ad916b180049d252 (patch)
tree24dbfe0561ac449ff84af9a6ca598b29f7d95bd4 /fs/binfmt_script.c
parent7d790d2da386a52cfebcf0c898ba927bece9d4ab (diff)
downloadlinux-stable-384632e67e0829deb8015ee6ad916b180049d252.tar.gz
linux-stable-384632e67e0829deb8015ee6ad916b180049d252.tar.bz2
linux-stable-384632e67e0829deb8015ee6ad916b180049d252.zip
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/20170920180413.26713-1-aarcange@redhat.com Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Reported-by: Mark Rutland <mark.rutland@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> Cc: Pavel Emelyanov <xemul@virtuozzo.com> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/binfmt_script.c')
0 files changed, 0 insertions, 0 deletions