[RFC PATCH v3 10/19] selftests/landlock: Test adding a rule with family and type outside the range
Mikhail Ivanov
ivanov.mikhail1 at huawei-partners.com
Wed Sep 4 10:48:15 UTC 2024
Create `prot_outside_range` fixture. It is used to iterate through
the various family and type pairs that do not fit the valid range.
Add test validating that adding a rule for sockets that do not match
the ranges (0 <= domain < AF_MAX), (0 <= type < SOCK_MAX) is prohibited.
Signed-off-by: Mikhail Ivanov <ivanov.mikhail1 at huawei-partners.com>
---
Changes since v2:
* Removes restriction checks on maximum family and type values. Such
checking is performed in protocol.create now.
* Renames this test into `rule_with_prot_outside_range`
* Creates `prot_outside_range` fixture. It is used to iterate through
the various family and type pairs that doesn't fit valid range.
Removes CHECK_RULE_OVERFLOW entries.
* Checks unrestricted socket(2) with family and type outside the range.
* Closes ruleset_fd.
* Refactors commit title.
---
.../testing/selftests/landlock/socket_test.c | 102 ++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/tools/testing/selftests/landlock/socket_test.c b/tools/testing/selftests/landlock/socket_test.c
index dee676c11227..047603abc5a7 100644
--- a/tools/testing/selftests/landlock/socket_test.c
+++ b/tools/testing/selftests/landlock/socket_test.c
@@ -479,4 +479,106 @@ TEST(ruleset_with_unknown_access)
}
}
+FIXTURE(prot_outside_range)
+{
+ struct protocol_variant prot;
+};
+
+FIXTURE_VARIANT(prot_outside_range)
+{
+ struct protocol_variant prot;
+};
+
+FIXTURE_SETUP(prot_outside_range)
+{
+ self->prot = variant->prot;
+};
+
+FIXTURE_TEARDOWN(prot_outside_range)
+{
+}
+
+/* Cf. include/linux/net.h */
+#define SOCK_MAX (SOCK_PACKET + 1)
+#define NEGATIVE_MAX (-1)
+/* Cf. linux/net.h */
+#define SOCK_TYPE_MASK 0xf
+
+#define SOCK_STREAM_FLAG1 (SOCK_STREAM | SOCK_NONBLOCK)
+#define SOCK_STREAM_FLAG2 (SOCK_STREAM | SOCK_CLOEXEC)
+
+#define INVAL_PROTOCOL_VARIANT_ADD(family_, type_) \
+ FIXTURE_VARIANT_ADD(prot_outside_range, family_##_##type_) \
+ { \
+ .prot = { \
+ .family = family_, \
+ .type = type_, \
+ }, \
+ }
+
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MIN, INT32_MIN);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MIN, NEGATIVE_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MIN, SOCK_STREAM);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MIN, SOCK_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MIN, INT32_MAX);
+
+INVAL_PROTOCOL_VARIANT_ADD(NEGATIVE_MAX, INT32_MIN);
+INVAL_PROTOCOL_VARIANT_ADD(NEGATIVE_MAX, NEGATIVE_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(NEGATIVE_MAX, SOCK_STREAM);
+INVAL_PROTOCOL_VARIANT_ADD(NEGATIVE_MAX, SOCK_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(NEGATIVE_MAX, INT32_MAX);
+
+INVAL_PROTOCOL_VARIANT_ADD(AF_INET, INT32_MIN);
+INVAL_PROTOCOL_VARIANT_ADD(AF_INET, NEGATIVE_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(AF_INET, SOCK_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(AF_INET, INT32_MAX);
+
+INVAL_PROTOCOL_VARIANT_ADD(AF_MAX, INT32_MIN);
+INVAL_PROTOCOL_VARIANT_ADD(AF_MAX, NEGATIVE_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(AF_MAX, SOCK_STREAM);
+INVAL_PROTOCOL_VARIANT_ADD(AF_MAX, SOCK_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(AF_MAX, INT32_MAX);
+
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MAX, INT32_MIN);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MAX, NEGATIVE_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MAX, SOCK_STREAM);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MAX, SOCK_MAX);
+INVAL_PROTOCOL_VARIANT_ADD(INT32_MAX, INT32_MAX);
+
+TEST_F(prot_outside_range, add_rule)
+{
+ int family = self->prot.family;
+ int type = self->prot.type;
+ const struct landlock_ruleset_attr ruleset_attr = {
+ .handled_access_socket = LANDLOCK_ACCESS_SOCKET_CREATE,
+ };
+ struct landlock_socket_attr create_socket_overflow = {
+ .allowed_access = LANDLOCK_ACCESS_SOCKET_CREATE,
+ .family = family,
+ .type = type,
+ };
+ int ruleset_fd;
+
+ /* Checks type flags using __sys_socket_create. */
+ if ((type & ~SOCK_TYPE_MASK) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
+ ASSERT_EQ(EINVAL, test_socket_variant(&self->prot));
+ }
+ /* Checks range using __sock_create. */
+ else if (family >= AF_MAX || family < 0) {
+ ASSERT_EQ(EAFNOSUPPORT, test_socket_variant(&self->prot));
+ } else {
+ ASSERT_EQ(EINVAL, test_socket_variant(&self->prot));
+ }
+
+ ruleset_fd =
+ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
+ ASSERT_LE(0, ruleset_fd);
+
+ EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_SOCKET,
+ &create_socket_overflow, 0));
+ EXPECT_EQ(EINVAL, errno);
+
+ ASSERT_EQ(0, close(ruleset_fd));
+}
+
TEST_HARNESS_MAIN
--
2.34.1
More information about the Linux-security-module-archive
mailing list