Add a regression test for executing memfd files

This commit is contained in:
Wang Siyuan 2025-10-23 08:50:50 +00:00 committed by Tate, Hongliang Tian
parent 449939a32b
commit a616682fe3
3 changed files with 74 additions and 1 deletions

View File

@ -0,0 +1,72 @@
// SPDX-License-Identifier: MPL-2.0
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include "../test.h"
#define EXECUTABLE_PATH "/test/execve/hello"
#define MFD_NAME "test_memfd_execve"
FN_TEST(memfd_noexec_seal)
{
int memfd = TEST_SUCC(
memfd_create(MFD_NAME, MFD_CLOEXEC | MFD_NOEXEC_SEAL));
TEST_RES(fcntl(memfd, F_GET_SEALS), _ret == F_SEAL_EXEC);
struct stat st;
TEST_RES(fstat(memfd, &st), (st.st_mode & 0777) == 0666);
TEST_ERRNO(fchmod(memfd, 0777), EPERM);
TEST_SUCC(close(memfd));
}
END_TEST()
FN_TEST(execveat_memfd)
{
int hello_fd = TEST_SUCC(open(EXECUTABLE_PATH, O_RDONLY));
int memfd = TEST_SUCC(
memfd_create(MFD_NAME, MFD_CLOEXEC | MFD_ALLOW_SEALING));
char buffer[65536];
ssize_t bytes_read;
while ((bytes_read =
TEST_SUCC(read(hello_fd, buffer, sizeof(buffer))))) {
TEST_RES(write(memfd, buffer, bytes_read), _ret == bytes_read);
}
TEST_SUCC(close(hello_fd));
TEST_SUCC(fcntl(memfd, F_ADD_SEALS, F_SEAL_EXEC));
TEST_RES(fcntl(memfd, F_GET_SEALS),
_ret == (F_SEAL_EXEC | F_SEAL_SHRINK | F_SEAL_GROW |
F_SEAL_WRITE | F_SEAL_FUTURE_WRITE));
pid_t pid = TEST_SUCC(fork());
if (pid == 0) {
struct stat st;
CHECK_WITH(fstat(memfd, &st),
_ret >= 0 && (st.st_mode & 0777) == 0777);
CHECK_WITH(fchmod(memfd, 0666), _ret < 0 && errno == EPERM);
char *const argv[] = { "memfd_hello", NULL };
char *const envp[] = { "PATH=/bin:/usr/bin", NULL };
CHECK(execveat(memfd, "", argv, envp, AT_EMPTY_PATH));
exit(EXIT_FAILURE);
}
int status = 0;
TEST_RES(wait4(pid, &status, 0, NULL),
_ret == pid && WIFEXITED(status) &&
WEXITSTATUS(status) == EXIT_SUCCESS);
}
END_TEST()

View File

@ -4,7 +4,7 @@
int main(int argc, char *argv[], char *envp[])
{
printf("Hello world from hello.c(execved in execve.c)!\n");
printf("Hello world from hello.c!\n");
printf("argc = %d\n", argc);
for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);

View File

@ -18,6 +18,7 @@ clone3/clone_process
cpu_affinity/cpu_affinity
execve/execve
execve/execve_mt_parent
execve/execve_memfd
exit/exit_code
exit/exit_procfs
eventfd2/eventfd2