mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-21 22:47:51 -04:00
selftests/landlock: Add test for TCP fast open
Enforce that TCP Fast Open is controlled by LANDLOCK_ACCESS_NET_CONNECT_TCP. Semantics of connect() and sendmsg(MSG_FASTOPEN) should be identical from Landlock's perspective. Also enforce error code consistency, since UDP sockets ignore the MSG_FASTOPEN flag while Unix sockets reject it. Signed-off-by: Matthieu Buffet <matthieu@buffet.re> Link: https://patch.msgid.link/20260701214628.33319-2-matthieu@buffet.re Cc: stable@vger.kernel.org [mic: Fix formatting] Signed-off-by: Mickaël Salaün <mic@digikod.net>
This commit is contained in:
committed by
Mickaël Salaün
parent
33cb713db0
commit
f4b30e0b1d
@@ -1281,6 +1281,103 @@ TEST_F(protocol, connect_unspec)
|
||||
EXPECT_EQ(0, close(bind_fd));
|
||||
}
|
||||
|
||||
TEST_F(protocol, tcp_fastopen)
|
||||
{
|
||||
const bool restricted = variant->sandbox == TCP_SANDBOX &&
|
||||
variant->prot.type == SOCK_STREAM &&
|
||||
(variant->prot.protocol == IPPROTO_TCP ||
|
||||
variant->prot.protocol == IPPROTO_IP) &&
|
||||
(variant->prot.domain == AF_INET ||
|
||||
variant->prot.domain == AF_INET6);
|
||||
const struct landlock_ruleset_attr ruleset_attr = {
|
||||
.handled_access_net = LANDLOCK_ACCESS_NET_CONNECT_TCP,
|
||||
};
|
||||
int bind_fd, client_fd, status;
|
||||
char buf;
|
||||
pid_t child;
|
||||
|
||||
bind_fd = socket_variant(&self->srv0);
|
||||
ASSERT_LE(0, bind_fd);
|
||||
EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0));
|
||||
if (self->srv0.protocol.type == SOCK_STREAM)
|
||||
EXPECT_EQ(0, listen(bind_fd, backlog));
|
||||
|
||||
child = fork();
|
||||
ASSERT_LE(0, child);
|
||||
if (child == 0) {
|
||||
int connect_fd, ret;
|
||||
|
||||
/* Closes listening socket for the child. */
|
||||
EXPECT_EQ(0, close(bind_fd));
|
||||
|
||||
connect_fd = socket_variant(&self->srv0);
|
||||
ASSERT_LE(0, connect_fd);
|
||||
|
||||
if (variant->sandbox == TCP_SANDBOX) {
|
||||
const int ruleset_fd = landlock_create_ruleset(
|
||||
&ruleset_attr, sizeof(ruleset_attr), 0);
|
||||
ASSERT_LE(0, ruleset_fd);
|
||||
|
||||
enforce_ruleset(_metadata, ruleset_fd);
|
||||
EXPECT_EQ(0, close(ruleset_fd));
|
||||
}
|
||||
|
||||
/* Fast Open with no address. */
|
||||
ret = sendto_variant(connect_fd, NULL, NULL, 0, MSG_FASTOPEN);
|
||||
if (self->srv0.protocol.domain == AF_UNIX) {
|
||||
EXPECT_EQ(-ENOTCONN, ret);
|
||||
} else if (self->srv0.protocol.type == SOCK_DGRAM) {
|
||||
EXPECT_EQ(-EDESTADDRREQ, ret);
|
||||
} else {
|
||||
EXPECT_EQ(-EINVAL, ret);
|
||||
}
|
||||
|
||||
/* Fast Open to a denied address. */
|
||||
ret = sendto_variant(connect_fd, &self->srv0, "A", 1,
|
||||
MSG_FASTOPEN);
|
||||
if (restricted) {
|
||||
EXPECT_EQ(-EACCES, ret);
|
||||
} else if (self->srv0.protocol.domain == AF_UNIX &&
|
||||
self->srv0.protocol.type == SOCK_STREAM) {
|
||||
EXPECT_EQ(-EOPNOTSUPP, ret);
|
||||
} else {
|
||||
EXPECT_EQ(0, ret);
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, close(connect_fd));
|
||||
_exit(_metadata->exit_code);
|
||||
return;
|
||||
}
|
||||
|
||||
client_fd = bind_fd;
|
||||
if (!restricted && self->srv0.protocol.type == SOCK_STREAM &&
|
||||
self->srv0.protocol.domain != AF_UNIX) {
|
||||
client_fd = accept(bind_fd, NULL, 0);
|
||||
ASSERT_LE(0, client_fd);
|
||||
}
|
||||
|
||||
if (restricted) {
|
||||
EXPECT_EQ(-1, read(client_fd, &buf, 1));
|
||||
EXPECT_EQ(ENOTCONN, errno);
|
||||
} else if (self->srv0.protocol.domain == AF_UNIX &&
|
||||
self->srv0.protocol.type == SOCK_STREAM) {
|
||||
EXPECT_EQ(-1, read(client_fd, &buf, 1));
|
||||
EXPECT_EQ(EINVAL, errno);
|
||||
} else {
|
||||
EXPECT_EQ(1, read(client_fd, &buf, 1));
|
||||
EXPECT_EQ('A', buf);
|
||||
}
|
||||
|
||||
EXPECT_EQ(child, waitpid(child, &status, 0));
|
||||
EXPECT_EQ(1, WIFEXITED(status));
|
||||
EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
|
||||
|
||||
if (client_fd != bind_fd)
|
||||
EXPECT_LE(0, close(client_fd));
|
||||
|
||||
EXPECT_EQ(0, close(bind_fd));
|
||||
}
|
||||
|
||||
TEST_F(protocol, sendmsg_stream)
|
||||
{
|
||||
int srv0_fd, tmp_fd, client_fd, res;
|
||||
|
||||
Reference in New Issue
Block a user