Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/memfd: add tests for F_SEAL_FUTURE_WRITE seal

Add tests to verify sealing memfds with the F_SEAL_FUTURE_WRITE works as
expected.

Link: http://lkml.kernel.org/r/20190112203816.85534-3-joel@joelfernandes.org
Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
Reviewed-by: Shuah Khan <shuah@kernel.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: J. Bruce Fields <bfields@fieldses.org>
Cc: Jeff Layton <jlayton@kernel.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Marc-Andr Lureau <marcandre.lureau@redhat.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Joel Fernandes (Google) and committed by
Linus Torvalds
54402986 ab3948f5

+74
+74
tools/testing/selftests/memfd/memfd_test.c
··· 54 54 return fd; 55 55 } 56 56 57 + static int mfd_assert_reopen_fd(int fd_in) 58 + { 59 + int r, fd; 60 + char path[100]; 61 + 62 + sprintf(path, "/proc/self/fd/%d", fd_in); 63 + 64 + fd = open(path, O_RDWR); 65 + if (fd < 0) { 66 + printf("re-open of existing fd %d failed\n", fd_in); 67 + abort(); 68 + } 69 + 70 + return fd; 71 + } 72 + 57 73 static void mfd_fail_new(const char *name, unsigned int flags) 58 74 { 59 75 int r; ··· 262 246 mfd_def_size, 263 247 PROT_READ | PROT_WRITE, 264 248 MAP_PRIVATE, 249 + fd, 250 + 0); 251 + if (p == MAP_FAILED) { 252 + printf("mmap() failed: %m\n"); 253 + abort(); 254 + } 255 + munmap(p, mfd_def_size); 256 + } 257 + 258 + /* Test that PROT_READ + MAP_SHARED mappings work. */ 259 + static void mfd_assert_read_shared(int fd) 260 + { 261 + void *p; 262 + 263 + /* verify PROT_READ and MAP_SHARED *is* allowed */ 264 + p = mmap(NULL, 265 + mfd_def_size, 266 + PROT_READ, 267 + MAP_SHARED, 265 268 fd, 266 269 0); 267 270 if (p == MAP_FAILED) { ··· 728 693 } 729 694 730 695 /* 696 + * Test SEAL_FUTURE_WRITE 697 + * Test whether SEAL_FUTURE_WRITE actually prevents modifications. 698 + */ 699 + static void test_seal_future_write(void) 700 + { 701 + int fd, fd2; 702 + void *p; 703 + 704 + printf("%s SEAL-FUTURE-WRITE\n", memfd_str); 705 + 706 + fd = mfd_assert_new("kern_memfd_seal_future_write", 707 + mfd_def_size, 708 + MFD_CLOEXEC | MFD_ALLOW_SEALING); 709 + 710 + p = mfd_assert_mmap_shared(fd); 711 + 712 + mfd_assert_has_seals(fd, 0); 713 + 714 + mfd_assert_add_seals(fd, F_SEAL_FUTURE_WRITE); 715 + mfd_assert_has_seals(fd, F_SEAL_FUTURE_WRITE); 716 + 717 + /* read should pass, writes should fail */ 718 + mfd_assert_read(fd); 719 + mfd_assert_read_shared(fd); 720 + mfd_fail_write(fd); 721 + 722 + fd2 = mfd_assert_reopen_fd(fd); 723 + /* read should pass, writes should still fail */ 724 + mfd_assert_read(fd2); 725 + mfd_assert_read_shared(fd2); 726 + mfd_fail_write(fd2); 727 + 728 + munmap(p, mfd_def_size); 729 + close(fd2); 730 + close(fd); 731 + } 732 + 733 + /* 731 734 * Test SEAL_SHRINK 732 735 * Test whether SEAL_SHRINK actually prevents shrinking 733 736 */ ··· 1018 945 test_basic(); 1019 946 1020 947 test_seal_write(); 948 + test_seal_future_write(); 1021 949 test_seal_shrink(); 1022 950 test_seal_grow(); 1023 951 test_seal_resize();