First published: Fri Dec 08 2017(Updated: )
A flaw was found in the Linux kernels handling of fork failure when dealing with event messages in the userfaultfd code. Failure to fork correctly can lead to a situation where a fork event will be removed from an already freed list of events with userfaultfd_ctx_put(). The userfault events are part of the slab cache, and the secondary free could only free other event list objects as the free mechanism uses the underlying kmem_cache_* implementation making generic use-after-free style attacks less effective. While technically a use after free style flaw, at this time Red Hat Product security believes this flaw to be difficult to exploit but this may change in the future. From the commit: 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 [forgotten] 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. -- end --- References: <a href="https://marc.info/?t=150351212000001&r=1&w=2">https://marc.info/?t=150351212000001&r=1&w=2</a> An upstream patch: <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=384632e67e0829deb8015ee6ad916b180049d252">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=384632e67e0829deb8015ee6ad916b180049d252</a>
Affected Software | Affected Version | How to fix |
---|---|---|
Red Hat Linux |
Sign up to SecAlerts for real-time vulnerability data matched to your software, aggregated from hundreds of sources.
The severity of REDHAT-BUG-1523481 is classified as moderate due to potential impacts on userfaultfd functionalities.
The fix for REDHAT-BUG-1523481 involves updating the Linux kernel to the latest patched version provided by Red Hat.
REDHAT-BUG-1523481 is caused by improper handling of fork failures in the userfaultfd code leading to potential instability.
REDHAT-BUG-1523481 affects specific versions of the Red Hat Linux Kernel that implement the userfaultfd functionality.
Currently, there are no known workarounds for REDHAT-BUG-1523481, and updating the kernel is recommended.