mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 14:53:58 -04:00
selftests/landlock: Test FD passing from restricted to unrestricted processes
A file descriptor created in a restricted process carries Landlock restrictions with it which will apply even if the same opened file is used from an unrestricted process. This change extracts suitable FD-passing helpers from base_test.c and moves them to common.h. We use the fixture variants from the ftruncate fixture to exercise the same scenarios as in the open_and_ftruncate test, but doing the Landlock restriction and open() in a different process than the ftruncate() call. Signed-off-by: Günther Noack <gnoack3000@gmail.com> Link: https://lore.kernel.org/r/20221018182216.301684-9-gnoack3000@gmail.com Signed-off-by: Mickaël Salaün <mic@digikod.net>
This commit is contained in:
committed by
Mickaël Salaün
parent
97b30f9e35
commit
a1a202a581
@@ -263,23 +263,6 @@ TEST(ruleset_fd_transfer)
|
||||
.allowed_access = LANDLOCK_ACCESS_FS_READ_DIR,
|
||||
};
|
||||
int ruleset_fd_tx, dir_fd;
|
||||
union {
|
||||
/* Aligned ancillary data buffer. */
|
||||
char buf[CMSG_SPACE(sizeof(ruleset_fd_tx))];
|
||||
struct cmsghdr _align;
|
||||
} cmsg_tx = {};
|
||||
char data_tx = '.';
|
||||
struct iovec io = {
|
||||
.iov_base = &data_tx,
|
||||
.iov_len = sizeof(data_tx),
|
||||
};
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &io,
|
||||
.msg_iovlen = 1,
|
||||
.msg_control = &cmsg_tx.buf,
|
||||
.msg_controllen = sizeof(cmsg_tx.buf),
|
||||
};
|
||||
struct cmsghdr *cmsg;
|
||||
int socket_fds[2];
|
||||
pid_t child;
|
||||
int status;
|
||||
@@ -298,33 +281,20 @@ TEST(ruleset_fd_transfer)
|
||||
&path_beneath_attr, 0));
|
||||
ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
ASSERT_NE(NULL, cmsg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(ruleset_fd_tx));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
memcpy(CMSG_DATA(cmsg), &ruleset_fd_tx, sizeof(ruleset_fd_tx));
|
||||
|
||||
/* Sends the ruleset FD over a socketpair and then close it. */
|
||||
ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0,
|
||||
socket_fds));
|
||||
ASSERT_EQ(sizeof(data_tx), sendmsg(socket_fds[0], &msg, 0));
|
||||
ASSERT_EQ(0, send_fd(socket_fds[0], ruleset_fd_tx));
|
||||
ASSERT_EQ(0, close(socket_fds[0]));
|
||||
ASSERT_EQ(0, close(ruleset_fd_tx));
|
||||
|
||||
child = fork();
|
||||
ASSERT_LE(0, child);
|
||||
if (child == 0) {
|
||||
int ruleset_fd_rx;
|
||||
const int ruleset_fd_rx = recv_fd(socket_fds[1]);
|
||||
|
||||
*(char *)msg.msg_iov->iov_base = '\0';
|
||||
ASSERT_EQ(sizeof(data_tx),
|
||||
recvmsg(socket_fds[1], &msg, MSG_CMSG_CLOEXEC));
|
||||
ASSERT_EQ('.', *(char *)msg.msg_iov->iov_base);
|
||||
ASSERT_LE(0, ruleset_fd_rx);
|
||||
ASSERT_EQ(0, close(socket_fds[1]));
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
ASSERT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(ruleset_fd_tx)));
|
||||
memcpy(&ruleset_fd_rx, CMSG_DATA(cmsg), sizeof(ruleset_fd_tx));
|
||||
|
||||
/* Enforces the received ruleset on the child. */
|
||||
ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
|
||||
|
||||
Reference in New Issue
Block a user