Message ID | 20220516152038.39594-12-konstantin.meskhidze@huawei.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | Network support for Landlock | expand |
I guess these tests would also work with IPv6. You can then use the "alternative" tests I explained. On 16/05/2022 17:20, Konstantin Meskhidze wrote: > Adds two selftests for connect() action with > AF_UNSPEC family flag. > The one is with no landlock restrictions > allows to disconnect already conneted socket > with connect(..., AF_UNSPEC, ...): > - connect_afunspec_no_restictions; > The second one refuses landlocked process > to disconnect already connected socket: > - connect_afunspec_with_restictions; > > Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com> > --- > > Changes since v3: > * Add connect_afunspec_no_restictions test. > * Add connect_afunspec_with_restictions test. > > Changes since v4: > * Refactoring code with self->port, self->addr4 variables. > * Adds bind() hook check for with AF_UNSPEC family. > > --- > tools/testing/selftests/landlock/net_test.c | 121 ++++++++++++++++++++ > 1 file changed, 121 insertions(+) > > diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c > index cf914d311eb3..bf8e49466d1d 100644 > --- a/tools/testing/selftests/landlock/net_test.c > +++ b/tools/testing/selftests/landlock/net_test.c > @@ -449,6 +449,7 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { > int new_fd; > int sockfd_1, sockfd_2; > pid_t child_1, child_2; > + > int status; > > struct landlock_ruleset_attr ruleset_attr = { > @@ -467,10 +468,12 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { > > const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, > sizeof(ruleset_attr), 0); > + Please no… > ASSERT_LE(0, ruleset_fd); > > /* Allows connect and bind operations to the port[0] socket */ > ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_SERVICE, > + ditto > &net_service_1, 0)); > /* Allows connect and deny bind operations to the port[1] socket */ > ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_SERVICE, > @@ -480,6 +483,7 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { > enforce_ruleset(_metadata, ruleset_fd); > > /* Creates a server socket 1 */ > + > sockfd_1 = create_socket(_metadata, true, false); > ASSERT_LE(0, sockfd_1); > > @@ -556,4 +560,121 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { > ASSERT_EQ(1, WIFEXITED(status)); > ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); > } > + > +TEST_F_FORK(socket_test, connect_afunspec_no_restictions) { > + > + int sockfd; > + pid_t child; > + int status; > + > + /* Creates a server socket 1 */ > + sockfd = create_socket(_metadata, false, false); > + ASSERT_LE(0, sockfd); > + > + /* Binds the socket 1 to address with port[0] with AF_UNSPEC family */ > + self->addr4[0].sin_family = AF_UNSPEC; > + ASSERT_EQ(0, bind(sockfd, (struct sockaddr *)&self->addr4[0], sizeof(self->addr4[0]))); > + > + /* Makes connection to socket with port[0] */ > + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&self->addr4[0], > + sizeof(self->addr4[0]))); > + > + child = fork(); > + ASSERT_LE(0, child); > + if (child == 0) { > + struct sockaddr addr_unspec = {.sa_family = AF_UNSPEC}; > + > + /* Child tries to disconnect already connected socket */ > + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&addr_unspec, > + sizeof(addr_unspec))); > + _exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE); > + return; > + } > + /* Closes listening socket 1 for the parent*/ > + ASSERT_EQ(0, close(sockfd)); > + > + ASSERT_EQ(child, waitpid(child, &status, 0)); > + ASSERT_EQ(1, WIFEXITED(status)); > + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); > +} > + > +TEST_F_FORK(socket_test, connect_afunspec_with_restictions) { > + > + int sockfd; > + pid_t child; > + int status; > + > + struct landlock_ruleset_attr ruleset_attr_1 = { > + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, > + }; > + struct landlock_net_service_attr net_service_1 = { > + .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, > + > + .port = self->port[0], > + }; > + > + struct landlock_ruleset_attr ruleset_attr_2 = { > + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | > + LANDLOCK_ACCESS_NET_CONNECT_TCP, > + }; > + struct landlock_net_service_attr net_service_2 = { > + .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | > + LANDLOCK_ACCESS_NET_CONNECT_TCP, > + > + .port = self->port[0], > + }; > + > + const int ruleset_fd_1 = landlock_create_ruleset(&ruleset_attr_1, > + sizeof(ruleset_attr_1), 0); > + ASSERT_LE(0, ruleset_fd_1); > + > + /* Allows bind operations to the port[0] socket */ > + ASSERT_EQ(0, landlock_add_rule(ruleset_fd_1, LANDLOCK_RULE_NET_SERVICE, > + &net_service_1, 0)); > + > + /* Enforces the ruleset. */ > + enforce_ruleset(_metadata, ruleset_fd_1); > + > + /* Creates a server socket 1 */ > + sockfd = create_socket(_metadata, false, false); > + ASSERT_LE(0, sockfd); > + > + /* Binds the socket 1 to address with port[0] with AF_UNSPEC family */ > + self->addr4[0].sin_family = AF_UNSPEC; > + ASSERT_EQ(0, bind(sockfd, (struct sockaddr *)&self->addr4[0], sizeof(self->addr4[0]))); > + > + /* Makes connection to socket with port[0] */ > + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&self->addr4[0], > + sizeof(self->addr4[0]))); > + > + const int ruleset_fd_2 = landlock_create_ruleset(&ruleset_attr_2, > + sizeof(ruleset_attr_2), 0); > + ASSERT_LE(0, ruleset_fd_2); > + > + /* Allows connect and bind operations to the port[0] socket */ > + ASSERT_EQ(0, landlock_add_rule(ruleset_fd_2, LANDLOCK_RULE_NET_SERVICE, > + &net_service_2, 0)); > + > + /* Enforces the ruleset. */ > + enforce_ruleset(_metadata, ruleset_fd_2); > + > + child = fork(); > + ASSERT_LE(0, child); > + if (child == 0) { > + struct sockaddr addr_unspec = {.sa_family = AF_UNSPEC}; > + > + /* Child tries to disconnect already connected socket */ > + ASSERT_EQ(-1, connect(sockfd, (struct sockaddr *)&addr_unspec, > + sizeof(addr_unspec))); > + ASSERT_EQ(EACCES, errno); > + _exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE); > + return; > + } > + /* Closes listening socket 1 for the parent*/ > + ASSERT_EQ(0, close(sockfd)); > + > + ASSERT_EQ(child, waitpid(child, &status, 0)); > + ASSERT_EQ(1, WIFEXITED(status)); > + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); > +} > TEST_HARNESS_MAIN > -- > 2.25.1 >
5/17/2022 11:55 AM, Mickaël Salaün пишет: > I guess these tests would also work with IPv6. You can then use the > "alternative" tests I explained. > Do you mean adding new helpers such as bind_variant() and connect_variant()?? > On 16/05/2022 17:20, Konstantin Meskhidze wrote: >> Adds two selftests for connect() action with >> AF_UNSPEC family flag. >> The one is with no landlock restrictions >> allows to disconnect already conneted socket >> with connect(..., AF_UNSPEC, ...): >> - connect_afunspec_no_restictions; >> The second one refuses landlocked process >> to disconnect already connected socket: >> - connect_afunspec_with_restictions; >> >> Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com> >> --- >> >> Changes since v3: >> * Add connect_afunspec_no_restictions test. >> * Add connect_afunspec_with_restictions test. >> >> Changes since v4: >> * Refactoring code with self->port, self->addr4 variables. >> * Adds bind() hook check for with AF_UNSPEC family. >> >> --- >> tools/testing/selftests/landlock/net_test.c | 121 ++++++++++++++++++++ >> 1 file changed, 121 insertions(+) >> >> diff --git a/tools/testing/selftests/landlock/net_test.c >> b/tools/testing/selftests/landlock/net_test.c >> index cf914d311eb3..bf8e49466d1d 100644 >> --- a/tools/testing/selftests/landlock/net_test.c >> +++ b/tools/testing/selftests/landlock/net_test.c >> @@ -449,6 +449,7 @@ TEST_F_FORK(socket_test, >> connect_with_restrictions_ip6) { >> int new_fd; >> int sockfd_1, sockfd_2; >> pid_t child_1, child_2; >> + >> int status; >> >> struct landlock_ruleset_attr ruleset_attr = { >> @@ -467,10 +468,12 @@ TEST_F_FORK(socket_test, >> connect_with_restrictions_ip6) { >> >> const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, >> sizeof(ruleset_attr), 0); >> + > > Please no… > Sorry for that. I will apply clang-format-14. > >> ASSERT_LE(0, ruleset_fd); >> >> /* Allows connect and bind operations to the port[0] socket */ >> ASSERT_EQ(0, landlock_add_rule(ruleset_fd, >> LANDLOCK_RULE_NET_SERVICE, >> + > > ditto Ditto. Will be fixed with clang-format. > >> &net_service_1, 0)); >> /* Allows connect and deny bind operations to the port[1] socket */ >> ASSERT_EQ(0, landlock_add_rule(ruleset_fd, >> LANDLOCK_RULE_NET_SERVICE, >> @@ -480,6 +483,7 @@ TEST_F_FORK(socket_test, >> connect_with_restrictions_ip6) { >> enforce_ruleset(_metadata, ruleset_fd); >> >> /* Creates a server socket 1 */ >> + >> sockfd_1 = create_socket(_metadata, true, false); >> ASSERT_LE(0, sockfd_1); >> >> @@ -556,4 +560,121 @@ TEST_F_FORK(socket_test, >> connect_with_restrictions_ip6) { >> ASSERT_EQ(1, WIFEXITED(status)); >> ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); >> } >> + >> +TEST_F_FORK(socket_test, connect_afunspec_no_restictions) { >> + >> + int sockfd; >> + pid_t child; >> + int status; >> + >> + /* Creates a server socket 1 */ >> + sockfd = create_socket(_metadata, false, false); >> + ASSERT_LE(0, sockfd); >> + >> + /* Binds the socket 1 to address with port[0] with AF_UNSPEC >> family */ >> + self->addr4[0].sin_family = AF_UNSPEC; >> + ASSERT_EQ(0, bind(sockfd, (struct sockaddr *)&self->addr4[0], >> sizeof(self->addr4[0]))); >> + >> + /* Makes connection to socket with port[0] */ >> + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&self->addr4[0], >> + sizeof(self->addr4[0]))); >> + >> + child = fork(); >> + ASSERT_LE(0, child); >> + if (child == 0) { >> + struct sockaddr addr_unspec = {.sa_family = AF_UNSPEC}; >> + >> + /* Child tries to disconnect already connected socket */ >> + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&addr_unspec, >> + sizeof(addr_unspec))); >> + _exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE); >> + return; >> + } >> + /* Closes listening socket 1 for the parent*/ >> + ASSERT_EQ(0, close(sockfd)); >> + >> + ASSERT_EQ(child, waitpid(child, &status, 0)); >> + ASSERT_EQ(1, WIFEXITED(status)); >> + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); >> +} >> + >> +TEST_F_FORK(socket_test, connect_afunspec_with_restictions) { >> + >> + int sockfd; >> + pid_t child; >> + int status; >> + >> + struct landlock_ruleset_attr ruleset_attr_1 = { >> + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, >> + }; >> + struct landlock_net_service_attr net_service_1 = { >> + .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, >> + >> + .port = self->port[0], >> + }; >> + >> + struct landlock_ruleset_attr ruleset_attr_2 = { >> + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | >> + LANDLOCK_ACCESS_NET_CONNECT_TCP, >> + }; >> + struct landlock_net_service_attr net_service_2 = { >> + .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | >> + LANDLOCK_ACCESS_NET_CONNECT_TCP, >> + >> + .port = self->port[0], >> + }; >> + >> + const int ruleset_fd_1 = landlock_create_ruleset(&ruleset_attr_1, >> + sizeof(ruleset_attr_1), 0); >> + ASSERT_LE(0, ruleset_fd_1); >> + >> + /* Allows bind operations to the port[0] socket */ >> + ASSERT_EQ(0, landlock_add_rule(ruleset_fd_1, >> LANDLOCK_RULE_NET_SERVICE, >> + &net_service_1, 0)); >> + >> + /* Enforces the ruleset. */ >> + enforce_ruleset(_metadata, ruleset_fd_1); >> + >> + /* Creates a server socket 1 */ >> + sockfd = create_socket(_metadata, false, false); >> + ASSERT_LE(0, sockfd); >> + >> + /* Binds the socket 1 to address with port[0] with AF_UNSPEC >> family */ >> + self->addr4[0].sin_family = AF_UNSPEC; >> + ASSERT_EQ(0, bind(sockfd, (struct sockaddr *)&self->addr4[0], >> sizeof(self->addr4[0]))); >> + >> + /* Makes connection to socket with port[0] */ >> + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&self->addr4[0], >> + sizeof(self->addr4[0]))); >> + >> + const int ruleset_fd_2 = landlock_create_ruleset(&ruleset_attr_2, >> + sizeof(ruleset_attr_2), 0); >> + ASSERT_LE(0, ruleset_fd_2); >> + >> + /* Allows connect and bind operations to the port[0] socket */ >> + ASSERT_EQ(0, landlock_add_rule(ruleset_fd_2, >> LANDLOCK_RULE_NET_SERVICE, >> + &net_service_2, 0)); >> + >> + /* Enforces the ruleset. */ >> + enforce_ruleset(_metadata, ruleset_fd_2); >> + >> + child = fork(); >> + ASSERT_LE(0, child); >> + if (child == 0) { >> + struct sockaddr addr_unspec = {.sa_family = AF_UNSPEC}; >> + >> + /* Child tries to disconnect already connected socket */ >> + ASSERT_EQ(-1, connect(sockfd, (struct sockaddr *)&addr_unspec, >> + sizeof(addr_unspec))); >> + ASSERT_EQ(EACCES, errno); >> + _exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE); >> + return; >> + } >> + /* Closes listening socket 1 for the parent*/ >> + ASSERT_EQ(0, close(sockfd)); >> + >> + ASSERT_EQ(child, waitpid(child, &status, 0)); >> + ASSERT_EQ(1, WIFEXITED(status)); >> + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); >> +} >> TEST_HARNESS_MAIN >> -- >> 2.25.1 >> > .
On 19/05/2022 14:31, Konstantin Meskhidze wrote: > > > 5/17/2022 11:55 AM, Mickaël Salaün пишет: >> I guess these tests would also work with IPv6. You can then use the >> "alternative" tests I explained. >> > Do you mean adding new helpers such as bind_variant() and > connect_variant()?? >> On 16/05/2022 17:20, Konstantin Meskhidze wrote: >>> Adds two selftests for connect() action with >>> AF_UNSPEC family flag. >>> The one is with no landlock restrictions >>> allows to disconnect already conneted socket >>> with connect(..., AF_UNSPEC, ...): >>> - connect_afunspec_no_restictions; >>> The second one refuses landlocked process >>> to disconnect already connected socket: >>> - connect_afunspec_with_restictions; >>> >>> Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com> >>> --- >>> >>> Changes since v3: >>> * Add connect_afunspec_no_restictions test. >>> * Add connect_afunspec_with_restictions test. >>> >>> Changes since v4: >>> * Refactoring code with self->port, self->addr4 variables. >>> * Adds bind() hook check for with AF_UNSPEC family. >>> >>> --- >>> tools/testing/selftests/landlock/net_test.c | 121 ++++++++++++++++++++ >>> 1 file changed, 121 insertions(+) >>> >>> diff --git a/tools/testing/selftests/landlock/net_test.c >>> b/tools/testing/selftests/landlock/net_test.c >>> index cf914d311eb3..bf8e49466d1d 100644 >>> --- a/tools/testing/selftests/landlock/net_test.c >>> +++ b/tools/testing/selftests/landlock/net_test.c >>> @@ -449,6 +449,7 @@ TEST_F_FORK(socket_test, >>> connect_with_restrictions_ip6) { >>> int new_fd; >>> int sockfd_1, sockfd_2; >>> pid_t child_1, child_2; >>> + >>> int status; >>> >>> struct landlock_ruleset_attr ruleset_attr = { >>> @@ -467,10 +468,12 @@ TEST_F_FORK(socket_test, >>> connect_with_restrictions_ip6) { >>> >>> const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, >>> sizeof(ruleset_attr), 0); >>> + >> >> Please no… >> > Sorry for that. I will apply clang-format-14. clang-format will not complain about these new lines. >> >>> ASSERT_LE(0, ruleset_fd); >>> >>> /* Allows connect and bind operations to the port[0] socket */ >>> ASSERT_EQ(0, landlock_add_rule(ruleset_fd, >>> LANDLOCK_RULE_NET_SERVICE, >>> + >> >> ditto > > Ditto. Will be fixed with clang-format.
On 19/05/2022 14:31, Konstantin Meskhidze wrote: > > > 5/17/2022 11:55 AM, Mickaël Salaün пишет: >> I guess these tests would also work with IPv6. You can then use the >> "alternative" tests I explained. >> > Do you mean adding new helpers such as bind_variant() and > connect_variant()?? Yes, reusing bind_variant() and adding connect_variant().
5/19/2022 6:00 PM, Mickaël Salaün пишет: > > On 19/05/2022 14:31, Konstantin Meskhidze wrote: >> >> >> 5/17/2022 11:55 AM, Mickaël Salaün пишет: >>> I guess these tests would also work with IPv6. You can then use the >>> "alternative" tests I explained. >>> >> Do you mean adding new helpers such as bind_variant() and >> connect_variant()?? >>> On 16/05/2022 17:20, Konstantin Meskhidze wrote: >>>> Adds two selftests for connect() action with >>>> AF_UNSPEC family flag. >>>> The one is with no landlock restrictions >>>> allows to disconnect already conneted socket >>>> with connect(..., AF_UNSPEC, ...): >>>> - connect_afunspec_no_restictions; >>>> The second one refuses landlocked process >>>> to disconnect already connected socket: >>>> - connect_afunspec_with_restictions; >>>> >>>> Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com> >>>> --- >>>> >>>> Changes since v3: >>>> * Add connect_afunspec_no_restictions test. >>>> * Add connect_afunspec_with_restictions test. >>>> >>>> Changes since v4: >>>> * Refactoring code with self->port, self->addr4 variables. >>>> * Adds bind() hook check for with AF_UNSPEC family. >>>> >>>> --- >>>> tools/testing/selftests/landlock/net_test.c | 121 >>>> ++++++++++++++++++++ >>>> 1 file changed, 121 insertions(+) >>>> >>>> diff --git a/tools/testing/selftests/landlock/net_test.c >>>> b/tools/testing/selftests/landlock/net_test.c >>>> index cf914d311eb3..bf8e49466d1d 100644 >>>> --- a/tools/testing/selftests/landlock/net_test.c >>>> +++ b/tools/testing/selftests/landlock/net_test.c >>>> @@ -449,6 +449,7 @@ TEST_F_FORK(socket_test, >>>> connect_with_restrictions_ip6) { >>>> int new_fd; >>>> int sockfd_1, sockfd_2; >>>> pid_t child_1, child_2; >>>> + >>>> int status; >>>> >>>> struct landlock_ruleset_attr ruleset_attr = { >>>> @@ -467,10 +468,12 @@ TEST_F_FORK(socket_test, >>>> connect_with_restrictions_ip6) { >>>> >>>> const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, >>>> sizeof(ruleset_attr), 0); >>>> + >>> >>> Please no… >>> >> Sorry for that. I will apply clang-format-14. > > clang-format will not complain about these new lines. Anyway I will check that no additional new lines appear. Thank you. > > >>> >>>> ASSERT_LE(0, ruleset_fd); >>>> >>>> /* Allows connect and bind operations to the port[0] socket */ >>>> ASSERT_EQ(0, landlock_add_rule(ruleset_fd, >>>> LANDLOCK_RULE_NET_SERVICE, >>>> + >>> >>> ditto >> >> Ditto. Will be fixed with clang-format. > .
5/19/2022 6:02 PM, Mickaël Salaün пишет: > > On 19/05/2022 14:31, Konstantin Meskhidze wrote: >> >> >> 5/17/2022 11:55 AM, Mickaël Salaün пишет: >>> I guess these tests would also work with IPv6. You can then use the >>> "alternative" tests I explained. >>> >> Do you mean adding new helpers such as bind_variant() and >> connect_variant()?? > > Yes, reusing bind_variant() and adding connect_variant(). Ok. I got it. Thanks! > .
diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c index cf914d311eb3..bf8e49466d1d 100644 --- a/tools/testing/selftests/landlock/net_test.c +++ b/tools/testing/selftests/landlock/net_test.c @@ -449,6 +449,7 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { int new_fd; int sockfd_1, sockfd_2; pid_t child_1, child_2; + int status; struct landlock_ruleset_attr ruleset_attr = { @@ -467,10 +468,12 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); /* Allows connect and bind operations to the port[0] socket */ ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_SERVICE, + &net_service_1, 0)); /* Allows connect and deny bind operations to the port[1] socket */ ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_SERVICE, @@ -480,6 +483,7 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { enforce_ruleset(_metadata, ruleset_fd); /* Creates a server socket 1 */ + sockfd_1 = create_socket(_metadata, true, false); ASSERT_LE(0, sockfd_1); @@ -556,4 +560,121 @@ TEST_F_FORK(socket_test, connect_with_restrictions_ip6) { ASSERT_EQ(1, WIFEXITED(status)); ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); } + +TEST_F_FORK(socket_test, connect_afunspec_no_restictions) { + + int sockfd; + pid_t child; + int status; + + /* Creates a server socket 1 */ + sockfd = create_socket(_metadata, false, false); + ASSERT_LE(0, sockfd); + + /* Binds the socket 1 to address with port[0] with AF_UNSPEC family */ + self->addr4[0].sin_family = AF_UNSPEC; + ASSERT_EQ(0, bind(sockfd, (struct sockaddr *)&self->addr4[0], sizeof(self->addr4[0]))); + + /* Makes connection to socket with port[0] */ + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&self->addr4[0], + sizeof(self->addr4[0]))); + + child = fork(); + ASSERT_LE(0, child); + if (child == 0) { + struct sockaddr addr_unspec = {.sa_family = AF_UNSPEC}; + + /* Child tries to disconnect already connected socket */ + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&addr_unspec, + sizeof(addr_unspec))); + _exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE); + return; + } + /* Closes listening socket 1 for the parent*/ + ASSERT_EQ(0, close(sockfd)); + + ASSERT_EQ(child, waitpid(child, &status, 0)); + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); +} + +TEST_F_FORK(socket_test, connect_afunspec_with_restictions) { + + int sockfd; + pid_t child; + int status; + + struct landlock_ruleset_attr ruleset_attr_1 = { + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, + }; + struct landlock_net_service_attr net_service_1 = { + .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, + + .port = self->port[0], + }; + + struct landlock_ruleset_attr ruleset_attr_2 = { + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | + LANDLOCK_ACCESS_NET_CONNECT_TCP, + }; + struct landlock_net_service_attr net_service_2 = { + .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | + LANDLOCK_ACCESS_NET_CONNECT_TCP, + + .port = self->port[0], + }; + + const int ruleset_fd_1 = landlock_create_ruleset(&ruleset_attr_1, + sizeof(ruleset_attr_1), 0); + ASSERT_LE(0, ruleset_fd_1); + + /* Allows bind operations to the port[0] socket */ + ASSERT_EQ(0, landlock_add_rule(ruleset_fd_1, LANDLOCK_RULE_NET_SERVICE, + &net_service_1, 0)); + + /* Enforces the ruleset. */ + enforce_ruleset(_metadata, ruleset_fd_1); + + /* Creates a server socket 1 */ + sockfd = create_socket(_metadata, false, false); + ASSERT_LE(0, sockfd); + + /* Binds the socket 1 to address with port[0] with AF_UNSPEC family */ + self->addr4[0].sin_family = AF_UNSPEC; + ASSERT_EQ(0, bind(sockfd, (struct sockaddr *)&self->addr4[0], sizeof(self->addr4[0]))); + + /* Makes connection to socket with port[0] */ + ASSERT_EQ(0, connect(sockfd, (struct sockaddr *)&self->addr4[0], + sizeof(self->addr4[0]))); + + const int ruleset_fd_2 = landlock_create_ruleset(&ruleset_attr_2, + sizeof(ruleset_attr_2), 0); + ASSERT_LE(0, ruleset_fd_2); + + /* Allows connect and bind operations to the port[0] socket */ + ASSERT_EQ(0, landlock_add_rule(ruleset_fd_2, LANDLOCK_RULE_NET_SERVICE, + &net_service_2, 0)); + + /* Enforces the ruleset. */ + enforce_ruleset(_metadata, ruleset_fd_2); + + child = fork(); + ASSERT_LE(0, child); + if (child == 0) { + struct sockaddr addr_unspec = {.sa_family = AF_UNSPEC}; + + /* Child tries to disconnect already connected socket */ + ASSERT_EQ(-1, connect(sockfd, (struct sockaddr *)&addr_unspec, + sizeof(addr_unspec))); + ASSERT_EQ(EACCES, errno); + _exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE); + return; + } + /* Closes listening socket 1 for the parent*/ + ASSERT_EQ(0, close(sockfd)); + + ASSERT_EQ(child, waitpid(child, &status, 0)); + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); +} TEST_HARNESS_MAIN
Adds two selftests for connect() action with AF_UNSPEC family flag. The one is with no landlock restrictions allows to disconnect already conneted socket with connect(..., AF_UNSPEC, ...): - connect_afunspec_no_restictions; The second one refuses landlocked process to disconnect already connected socket: - connect_afunspec_with_restictions; Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com> --- Changes since v3: * Add connect_afunspec_no_restictions test. * Add connect_afunspec_with_restictions test. Changes since v4: * Refactoring code with self->port, self->addr4 variables. * Adds bind() hook check for with AF_UNSPEC family. --- tools/testing/selftests/landlock/net_test.c | 121 ++++++++++++++++++++ 1 file changed, 121 insertions(+) -- 2.25.1