Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac8ed5f9 authored by Joel Fernandes (Google)'s avatar Joel Fernandes (Google) Committed by Joel Fernandes
Browse files

UPSTREAM: 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.

Cc: dancol@google.com
Cc: minchan@kernel.org
Cc: Jann Horn <jannh@google.com>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: default avatarJoel Fernandes (Google) <joel@joelfernandes.org>
Reviewed-by: default avatarShuah Khan <shuah@kernel.org>
Change-Id: I42a0ceb1f584a5444ec755f8c76899499bcbaddd
parent dec031f6
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -54,6 +54,22 @@ static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags)
	return fd;
}

static int mfd_assert_reopen_fd(int fd_in)
{
	int r, fd;
	char path[100];

	sprintf(path, "/proc/self/fd/%d", fd_in);

	fd = open(path, O_RDWR);
	if (fd < 0) {
		printf("re-open of existing fd %d failed\n", fd_in);
		abort();
	}

	return fd;
}

static void mfd_fail_new(const char *name, unsigned int flags)
{
	int r;
@@ -255,6 +271,25 @@ static void mfd_assert_read(int fd)
	munmap(p, mfd_def_size);
}

/* Test that PROT_READ + MAP_SHARED mappings work. */
static void mfd_assert_read_shared(int fd)
{
	void *p;

	/* verify PROT_READ and MAP_SHARED *is* allowed */
	p = mmap(NULL,
		 mfd_def_size,
		 PROT_READ,
		 MAP_SHARED,
		 fd,
		 0);
	if (p == MAP_FAILED) {
		printf("mmap() failed: %m\n");
		abort();
	}
	munmap(p, mfd_def_size);
}

static void mfd_assert_write(int fd)
{
	ssize_t l;
@@ -692,6 +727,44 @@ static void test_seal_write(void)
	close(fd);
}

/*
 * Test SEAL_FUTURE_WRITE
 * Test whether SEAL_FUTURE_WRITE actually prevents modifications.
 */
static void test_seal_future_write(void)
{
	int fd, fd2;
	void *p;

	printf("%s SEAL-FUTURE-WRITE\n", memfd_str);

	fd = mfd_assert_new("kern_memfd_seal_future_write",
			    mfd_def_size,
			    MFD_CLOEXEC | MFD_ALLOW_SEALING);

	p = mfd_assert_mmap_shared(fd);

	mfd_assert_has_seals(fd, 0);

	mfd_assert_add_seals(fd, F_SEAL_FUTURE_WRITE);
	mfd_assert_has_seals(fd, F_SEAL_FUTURE_WRITE);

	/* read should pass, writes should fail */
	mfd_assert_read(fd);
	mfd_assert_read_shared(fd);
	mfd_fail_write(fd);

	fd2 = mfd_assert_reopen_fd(fd);
	/* read should pass, writes should still fail */
	mfd_assert_read(fd2);
	mfd_assert_read_shared(fd2);
	mfd_fail_write(fd2);

	munmap(p, mfd_def_size);
	close(fd2);
	close(fd);
}

/*
 * Test SEAL_SHRINK
 * Test whether SEAL_SHRINK actually prevents shrinking
@@ -945,6 +1018,7 @@ int main(int argc, char **argv)
	test_basic();

	test_seal_write();
	test_seal_future_write();
	test_seal_shrink();
	test_seal_grow();
	test_seal_resize();