Extend protocol fixture with test suits for SCTP protocol. Add CONFIG_IP_SCTP option in config. Signed-off-by: Mikhail Ivanov <ivanov.mikhail1@xxxxxxxxxxxxxxxxxxx> --- tools/testing/selftests/landlock/config | 1 + tools/testing/selftests/landlock/net_test.c | 83 ++++++++++++++++++--- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/landlock/config b/tools/testing/selftests/landlock/config index 52988e8a56cc..a96d42dc850d 100644 --- a/tools/testing/selftests/landlock/config +++ b/tools/testing/selftests/landlock/config @@ -1,6 +1,7 @@ CONFIG_CGROUPS=y CONFIG_CGROUP_SCHED=y CONFIG_INET=y +CONFIG_IP_SCTP=y CONFIG_IPV6=y CONFIG_KEYS=y CONFIG_LSM="landlock" diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c index 30b29bf10bdc..fa382a2e3b58 100644 --- a/tools/testing/selftests/landlock/net_test.c +++ b/tools/testing/selftests/landlock/net_test.c @@ -97,13 +97,28 @@ static void setup_loopback(struct __test_metadata *const _metadata) clear_ambient_cap(_metadata, CAP_NET_ADMIN); } -static bool prot_is_tcp(const struct protocol_variant *const prot) +static bool prot_is_inet_stream(const struct protocol_variant *const prot) { return (prot->domain == AF_INET || prot->domain == AF_INET6) && - prot->type == SOCK_STREAM && + prot->type == SOCK_STREAM; +} + +static bool prot_is_tcp(const struct protocol_variant *const prot) +{ + return prot_is_inet_stream(prot) && (prot->protocol == IPPROTO_TCP || prot->protocol == IPPROTO_IP); } +static bool prot_is_sctp(const struct protocol_variant *const prot) +{ + return prot_is_inet_stream(prot) && prot->protocol == IPPROTO_SCTP; +} + +static bool prot_is_unix_stream(const struct protocol_variant *const prot) +{ + return prot->domain == AF_UNIX && prot->type == SOCK_STREAM; +} + static bool is_restricted(const struct protocol_variant *const prot, const enum sandbox_type sandbox) { @@ -357,6 +372,17 @@ FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_mptcp) { }, }; +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_sctp) { + /* clang-format on */ + .sandbox = NO_SANDBOX, + .prot = { + .domain = AF_INET, + .type = SOCK_STREAM, + .protocol = IPPROTO_SCTP, + }, +}; + /* clang-format off */ FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp1) { /* clang-format on */ @@ -391,6 +417,17 @@ FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_mptcp) { }, }; +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_sctp) { + /* clang-format on */ + .sandbox = NO_SANDBOX, + .prot = { + .domain = AF_INET6, + .type = SOCK_STREAM, + .protocol = IPPROTO_SCTP, + }, +}; + /* clang-format off */ FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_udp) { /* clang-format on */ @@ -465,6 +502,17 @@ FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_mptcp) { }, }; +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_sctp) { + /* clang-format on */ + .sandbox = TCP_SANDBOX, + .prot = { + .domain = AF_INET, + .type = SOCK_STREAM, + .protocol = IPPROTO_SCTP, + }, +}; + /* clang-format off */ FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp1) { /* clang-format on */ @@ -499,6 +547,17 @@ FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_mptcp) { }, }; +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_sctp) { + /* clang-format on */ + .sandbox = TCP_SANDBOX, + .prot = { + .domain = AF_INET6, + .type = SOCK_STREAM, + .protocol = IPPROTO_SCTP, + }, +}; + /* clang-format off */ FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_udp) { /* clang-format on */ @@ -793,7 +852,7 @@ TEST_F(protocol, bind_unspec) /* Allowed bind on AF_UNSPEC/INADDR_ANY. */ ret = bind_variant(bind_fd, &self->unspec_any0); - if (variant->prot.domain == AF_INET) { + if (variant->prot.domain == AF_INET && !prot_is_sctp(&variant->prot)) { EXPECT_EQ(0, ret) { TH_LOG("Failed to bind to unspec/any socket: %s", @@ -819,7 +878,7 @@ TEST_F(protocol, bind_unspec) /* Denied bind on AF_UNSPEC/INADDR_ANY. */ ret = bind_variant(bind_fd, &self->unspec_any0); - if (variant->prot.domain == AF_INET) { + if (variant->prot.domain == AF_INET && !prot_is_sctp(&variant->prot)) { if (is_restricted(&variant->prot, variant->sandbox)) { EXPECT_EQ(-EACCES, ret); } else { @@ -834,7 +893,7 @@ TEST_F(protocol, bind_unspec) bind_fd = socket_variant(&self->srv0); ASSERT_LE(0, bind_fd); ret = bind_variant(bind_fd, &self->unspec_srv0); - if (variant->prot.domain == AF_INET) { + if (variant->prot.domain == AF_INET && !prot_is_sctp(&variant->prot)) { EXPECT_EQ(-EAFNOSUPPORT, ret); } else { EXPECT_EQ(-EINVAL, ret) @@ -899,17 +958,18 @@ TEST_F(protocol, connect_unspec) /* Disconnects already connected socket, or set peer. */ ret = connect_variant(connect_fd, &self->unspec_any0); - if (self->srv0.protocol.domain == AF_UNIX && - self->srv0.protocol.type == SOCK_STREAM) { + if (prot_is_unix_stream(&variant->prot)) { EXPECT_EQ(-EINVAL, ret); + } else if (prot_is_sctp(&variant->prot)) { + EXPECT_EQ(-EOPNOTSUPP, ret); } else { EXPECT_EQ(0, ret); } /* Tries to reconnect, or set peer. */ ret = connect_variant(connect_fd, &self->srv0); - if (self->srv0.protocol.domain == AF_UNIX && - self->srv0.protocol.type == SOCK_STREAM) { + if (prot_is_unix_stream(&variant->prot) || + prot_is_sctp(&variant->prot)) { EXPECT_EQ(-EISCONN, ret); } else { EXPECT_EQ(0, ret); @@ -926,9 +986,10 @@ TEST_F(protocol, connect_unspec) } ret = connect_variant(connect_fd, &self->unspec_any0); - if (self->srv0.protocol.domain == AF_UNIX && - self->srv0.protocol.type == SOCK_STREAM) { + if (prot_is_unix_stream(&variant->prot)) { EXPECT_EQ(-EINVAL, ret); + } else if (prot_is_sctp(&variant->prot)) { + EXPECT_EQ(-EOPNOTSUPP, ret); } else { /* Always allowed to disconnect. */ EXPECT_EQ(0, ret); -- 2.34.1