Skip to content

Commit cb185d5

Browse files
anadavtorvalds
authored andcommitted
userfaultfd: fix a race between writeprotect and exit_mmap()
A race is possible when a process exits, its VMAs are removed by exit_mmap() and at the same time userfaultfd_writeprotect() is called. The race was detected by KASAN on a development kernel, but it appears to be possible on vanilla kernels as well. Use mmget_not_zero() to prevent the race as done in other userfaultfd operations. Link: https://lkml.kernel.org/r/20210921200247.25749-1-namit@vmware.com Fixes: 63b2d41 ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl") Signed-off-by: Nadav Amit <namit@vmware.com> Tested-by: Li Wang <liwang@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 8913970 commit cb185d5

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

fs/userfaultfd.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,9 +1827,15 @@ static int userfaultfd_writeprotect(struct userfaultfd_ctx *ctx,
18271827
if (mode_wp && mode_dontwake)
18281828
return -EINVAL;
18291829

1830-
ret = mwriteprotect_range(ctx->mm, uffdio_wp.range.start,
1831-
uffdio_wp.range.len, mode_wp,
1832-
&ctx->mmap_changing);
1830+
if (mmget_not_zero(ctx->mm)) {
1831+
ret = mwriteprotect_range(ctx->mm, uffdio_wp.range.start,
1832+
uffdio_wp.range.len, mode_wp,
1833+
&ctx->mmap_changing);
1834+
mmput(ctx->mm);
1835+
} else {
1836+
return -ESRCH;
1837+
}
1838+
18331839
if (ret)
18341840
return ret;
18351841

0 commit comments

Comments
 (0)