Skip to content

Commit 9cb189a

Browse files
thejhvivekkreddy
authored andcommitted
udmabuf: fix racy memfd sealing check
The current check_memfd_seals() is racy: Since we first do check_memfd_seals() and then udmabuf_pin_folios() without holding any relevant lock across both, F_SEAL_WRITE can be set in between. This is problematic because we can end up holding pins to pages in a write-sealed memfd. Fix it using the inode lock, that's probably the easiest way. In the future, we might want to consider moving this logic into memfd, especially if anyone else wants to use memfd_pin_folios(). Reported-by: Julian Orth <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219106 Closes: https://lore.kernel.org/r/CAG48ez0w8HrFEZtJkfmkVKFDhE5aP7nz=obrimeTgpD+StkV9w@mail.gmail.com Fixes: fbb0de7 ("Add udmabuf misc device") Cc: [email protected] Signed-off-by: Jann Horn <[email protected]> Acked-by: Joel Fernandes (Google) <[email protected]> Acked-by: Vivek Kasireddy <[email protected]> Signed-off-by: Vivek Kasireddy <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 2872e21 commit 9cb189a

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

drivers/dma-buf/udmabuf.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,14 +436,19 @@ static long udmabuf_create(struct miscdevice *device,
436436
goto err;
437437
}
438438

439+
/*
440+
* Take the inode lock to protect against concurrent
441+
* memfd_add_seals(), which takes this lock in write mode.
442+
*/
443+
inode_lock_shared(file_inode(memfd));
439444
ret = check_memfd_seals(memfd);
440-
if (ret < 0) {
441-
fput(memfd);
442-
goto err;
443-
}
445+
if (ret)
446+
goto out_unlock;
444447

445448
ret = udmabuf_pin_folios(ubuf, memfd, list[i].offset,
446449
list[i].size, folios);
450+
out_unlock:
451+
inode_unlock_shared(file_inode(memfd));
447452
fput(memfd);
448453
if (ret)
449454
goto err;

0 commit comments

Comments
 (0)