From b39f5cfa2ee6537b98bcd3703c265a5dd83e4be8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Oct 2026 02:54:44 +0900 Subject: [PATCH] memfd-util: introduce memfd_set_sealed_gracefully() (cherry picked from commit d2810b5c790e0a80f8fe1a68fa53054c34414b3d) --- src/basic/memfd-util.c | 16 ++++++++++++++++ src/basic/memfd-util.h | 1 + src/test/test-memfd-util.c | 5 ++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/basic/memfd-util.c b/src/basic/memfd-util.c index 946acb8751..0a75ed79fb 100644 --- a/src/basic/memfd-util.c +++ b/src/basic/memfd-util.c @@ -101,6 +101,22 @@ int memfd_get_sealed(int fd) { return FLAGS_SET(seals, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE); } +int memfd_set_sealed_gracefully(int fd) { + int r; + + r = memfd_set_sealed(fd); + if (r != -EPERM) + return r; + + /* Already sealed? Check if required seals are set. */ + r = memfd_get_sealed(fd); + if (r < 0) + return r; + if (r == 0) + return -EPERM; /* Propagate the original error. */ + return 0; +} + int memfd_get_size(int fd, uint64_t *ret) { struct stat stat; diff --git a/src/basic/memfd-util.h b/src/basic/memfd-util.h index befe41ac43..706d085bed 100644 --- a/src/basic/memfd-util.h +++ b/src/basic/memfd-util.h @@ -19,6 +19,7 @@ static inline int memfd_new_and_seal_string(const char *name, const char *s) { int memfd_set_sealed(int fd); int memfd_get_sealed(int fd); +int memfd_set_sealed_gracefully(int fd); int memfd_get_size(int fd, uint64_t *ret); int memfd_set_size(int fd, uint64_t sz); diff --git a/src/test/test-memfd-util.c b/src/test/test-memfd-util.c index 971a9a8dc0..d7daf78fd4 100644 --- a/src/test/test-memfd-util.c +++ b/src/test/test-memfd-util.c @@ -31,8 +31,11 @@ TEST(memfd_get_sealed) { ASSERT_EQ(size, new_size / 2); ASSERT_OK_ZERO(memfd_get_sealed(fd)); - ASSERT_OK(memfd_set_sealed(fd)); + ASSERT_OK(memfd_set_sealed_gracefully(fd)); ASSERT_OK_POSITIVE(memfd_get_sealed(fd)); + ASSERT_OK(memfd_set_sealed_gracefully(fd)); + ASSERT_OK_POSITIVE(memfd_get_sealed(fd)); + ASSERT_ERROR(memfd_set_sealed(fd), EPERM); } DEFINE_TEST_MAIN(LOG_DEBUG);