From: Jeff Xu jeffxu@chromium.org
When apply F_SEAL_EXEC to an executable memfd, add write seals also to prevent modification of memfd.
Signed-off-by: Jeff Xu jeffxu@chromium.org --- mm/memfd.c | 3 +++ tools/testing/selftests/memfd/memfd_test.c | 25 ++++++++++++++++++++++ 2 files changed, 28 insertions(+)
diff --git a/mm/memfd.c b/mm/memfd.c index 96dcfbfed09e..3a04c0698957 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -222,6 +222,9 @@ static int memfd_add_seals(struct file *file, unsigned int seals) } }
+ if (seals & F_SEAL_EXEC && inode->i_mode & 0111) + seals |= F_ALL_SEALS; + *file_seals |= seals; error = 0;
diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c index 775c9e6c061e..0731e5b3cdce 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c @@ -32,6 +32,13 @@ #define F_SEAL_EXEC 0x0020 #endif
+#define F_ALL_SEALS (F_SEAL_SEAL | \ + F_SEAL_SHRINK | \ + F_SEAL_GROW | \ + F_SEAL_WRITE | \ + F_SEAL_FUTURE_WRITE | \ + F_SEAL_EXEC) + #ifndef MAX_PATH #define MAX_PATH 256 #endif @@ -1006,6 +1013,7 @@ static void test_exec_seal(void)
printf("%s SEAL-EXEC\n", memfd_str);
+ printf("%s Apply SEAL_EXEC\n", memfd_str); fd = mfd_assert_new("kern_memfd_seal_exec", mfd_def_size, MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_EXEC); @@ -1024,7 +1032,24 @@ static void test_exec_seal(void) mfd_fail_chmod(fd, 0700); mfd_fail_chmod(fd, 0100); mfd_assert_chmod(fd, 0666); + mfd_assert_write(fd); + close(fd); + + printf("%s Apply ALL_SEALS\n", memfd_str); + fd = mfd_assert_new("kern_memfd_seal_exec", + mfd_def_size, + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_EXEC);
+ mfd_assert_mode(fd, 0777); + mfd_assert_chmod(fd, 0700); + + mfd_assert_has_seals(fd, 0); + mfd_assert_add_seals(fd, F_SEAL_EXEC); + mfd_assert_has_seals(fd, F_ALL_SEALS); + + mfd_fail_chmod(fd, 0711); + mfd_fail_chmod(fd, 0600); + mfd_fail_write(fd); close(fd); }