From 26e7249f44704ee4302f772de1b8123c00daf7a3 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 3 Apr 2024 07:36:35 +0000 Subject: [PATCH] Merge tests: fix inet tests Fixes: https://gitlab.com/apparmor/apparmor/-/issues/376 MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1192 Approved-by: John Johansen Merged-by: John Johansen (cherry picked from commit 01fcce41dceffe15b22c46c155e2dca6ce6695d8) Signed-off-by: John Johansen --- .gitignore | 4 +- tests/regression/apparmor/Makefile | 4 +- .../{net_finegrained.h => net_inet.h} | 0 .../{net_finegrained.sh => net_inet.sh} | 25 +- .../{net_finegrained_rcv.c => net_inet_rcv.c} | 283 ++++++++---------- .../{net_finegrained_snd.c => net_inet_snd.c} | 48 +-- 6 files changed, 151 insertions(+), 213 deletions(-) rename tests/regression/apparmor/{net_finegrained.h => net_inet.h} (100%) rename tests/regression/apparmor/{net_finegrained.sh => net_inet.sh} (92%) rename tests/regression/apparmor/{net_finegrained_rcv.c => net_inet_rcv.c} (65%) rename tests/regression/apparmor/{net_finegrained_snd.c => net_inet_snd.c} (93%) diff --git a/.gitignore b/.gitignore index 2c779f2ae..f78a9901e 100644 --- a/.gitignore +++ b/.gitignore @@ -266,8 +266,8 @@ tests/regression/apparmor/mmap tests/regression/apparmor/mount tests/regression/apparmor/move_mount tests/regression/apparmor/named_pipe -tests/regression/apparmor/net_finegrained_rcv -tests/regression/apparmor/net_finegrained_snd +tests/regression/apparmor/net_inet_rcv +tests/regression/apparmor/net_inet_snd tests/regression/apparmor/net_raw tests/regression/apparmor/open tests/regression/apparmor/openat diff --git a/tests/regression/apparmor/Makefile b/tests/regression/apparmor/Makefile index fde2958f8..551ff538c 100644 --- a/tests/regression/apparmor/Makefile +++ b/tests/regression/apparmor/Makefile @@ -111,8 +111,8 @@ SRC=access.c \ mount.c \ move_mount.c \ named_pipe.c \ - net_finegrained_rcv.c \ - net_finegrained_snd.c \ + net_inet_rcv.c \ + net_inet_snd.c \ net_raw.c \ open.c \ openat.c \ diff --git a/tests/regression/apparmor/net_finegrained.h b/tests/regression/apparmor/net_inet.h similarity index 100% rename from tests/regression/apparmor/net_finegrained.h rename to tests/regression/apparmor/net_inet.h diff --git a/tests/regression/apparmor/net_finegrained.sh b/tests/regression/apparmor/net_inet.sh similarity index 92% rename from tests/regression/apparmor/net_finegrained.sh rename to tests/regression/apparmor/net_inet.sh index 0e5b9f24a..f5060740a 100644 --- a/tests/regression/apparmor/net_finegrained.sh +++ b/tests/regression/apparmor/net_inet.sh @@ -6,9 +6,9 @@ #published by the Free Software Foundation, version 2 of the #License. -#=NAME posix_mq +#=NAME net_inet #=DESCRIPTION -# This test verifies if mediation of posix message queues is working +# This test verifies if finegrained inet mediation is working #=END pwd=`dirname $0` @@ -18,13 +18,13 @@ bin=$pwd . $bin/prologue.inc -#requires_kernel_features network_v8/finegrained +requires_kernel_features network_v8/af_inet requires_parser_support "network ip=::1," -settest net_finegrained_rcv +settest net_inet_rcv -sender="$bin/net_finegrained_snd" -receiver="$bin/net_finegrained_rcv" +sender="$bin/net_inet_snd" +receiver="$bin/net_inet_rcv" # local ipv6 address generated according to https://www.rfc-editor.org/rfc/rfc4193.html #ipv6_subnet=fd74:1820:b03a:b361::/64 @@ -47,7 +47,7 @@ do_onexit="cleanup" do_test() { - local desc="FINEGRAINED NETWORK ($1)" + local desc="NETWORK INET ($1)" shift runchecktest "$desc" "$@" } @@ -65,12 +65,11 @@ do_tests() protocol=$8 generate_profile=$9 - settest net_finegrained_rcv + settest net_inet_rcv $generate_profile do_test "$prefix - root" $expect_rcv --bind_ip $bind_ip --bind_port $bind_port --remote_ip $remote_ip --remote_port $remote_port --protocol $protocol --timeout 5 --sender $sender - - settest -u "foo" net_finegrained_rcv + settest -u "foo" net_inet_rcv $generate_profile do_test "$prefix - user" $expect_rcv --bind_ip $bind_ip --bind_port $bind_port --remote_ip $remote_ip --remote_port $remote_port --protocol $protocol --timeout 5 --sender $sender @@ -97,7 +96,7 @@ do_tests "ipv4 udp no conds" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remot generate_profile="genprofile network $sender:px -- image=$sender network" do_tests "ipv4 tcp no conds" pass pass $bind_ipv4 $bind_port $remote_ipv4 $remote_port tcp "$generate_profile" -setsockopt_rules="network;(setopt,getopt);ip=0.0.0.0;port=0" +setsockopt_rules="network;(setopt,getopt);ip=0.0.0.0;port=0" # INADDR_ANY rcv_rules="network;ip=$bind_ipv4;peer=(ip=anon)" snd_rules="network;ip=$remote_ipv4;peer=(ip=anon)" @@ -126,7 +125,7 @@ do_tests "ipv6 udp no conds" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remot generate_profile="genprofile network $sender:px -- image=$sender network" do_tests "ipv6 tcp no conds" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port tcp "$generate_profile" -setsockopt_rules="network;(setopt,getopt);ip=::0;port=0" +setsockopt_rules="network;(setopt,getopt);ip=::0;port=0" # IN6ADDR_ANY_INIT rcv_rules="network;ip=$bind_ipv6;peer=(ip=anon)" snd_rules="network;ip=$remote_ipv6;peer=(ip=anon)" @@ -135,5 +134,3 @@ do_tests "ipv6 udp generic perms" pass pass $bind_ipv6 $bind_port $remote_ipv6 $ generate_profile="genprofile network;ip=$bind_ipv6;port=$bind_port;peer=(ip=$remote_ipv6,port=$remote_port) $setsockopt_rules $rcv_rules $sender:px -- image=$sender network;ip=$remote_ipv6;port=$remote_port;peer=(ip=$bind_ipv6,port=$bind_port) $setsockopt_rules $snd_rules" do_tests "ipv6 tcp generic perms" pass pass $bind_ipv6 $bind_port $remote_ipv6 $remote_port tcp "$generate_profile" - - diff --git a/tests/regression/apparmor/net_finegrained_rcv.c b/tests/regression/apparmor/net_inet_rcv.c similarity index 65% rename from tests/regression/apparmor/net_finegrained_rcv.c rename to tests/regression/apparmor/net_inet_rcv.c index b426b85fc..214070a3d 100644 --- a/tests/regression/apparmor/net_finegrained_rcv.c +++ b/tests/regression/apparmor/net_inet_rcv.c @@ -9,7 +9,13 @@ #include #include #include -#include "net_finegrained.h" +#include "net_inet.h" + +enum protocol { + UDP, + TCP, + ICMP +}; struct connection_info { char *bind_ip; @@ -17,17 +23,72 @@ struct connection_info { char *remote_ip; char *remote_port; char *protocol; + enum protocol prot; int timeout; } net_info; - -int receive_udp() +int receive_bind() { - int sock; - char *buf; struct sockaddr_in local; struct sockaddr_in6 local6; + + struct ip_address bind_addr; + + if (!parse_ip(net_info.bind_ip, net_info.bind_port, &bind_addr)) { + fprintf(stderr, "FAIL - could not parse bind ip address\n"); + return -1; + } + + switch(net_info.prot) { + case UDP: + sock = socket(bind_addr.family, SOCK_DGRAM, 0); + break; + case TCP: + sock = socket(bind_addr.family, SOCK_STREAM, 0); + break; + case ICMP: + sock = socket(bind_addr.family, SOCK_DGRAM, IPPROTO_ICMP); + break; + } + + if (sock < 0) { + perror("FAIL - Socket error: "); + return -1; + } + + const int enable = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0) + perror("FAIL - setsockopt(SO_REUSEADDR) failed"); + + if (bind_addr.family == AF_INET) { + local = convert_to_sockaddr_in(bind_addr); + if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { + perror("FAIL - Bind error: "); + return -1; + } + } else { + local6 = convert_to_sockaddr_in6(bind_addr); + if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0) { + perror("FAIL - Bind error: "); + return -1; + } + } + + if (net_info.prot == TCP) { + if (listen(sock, 5) == -1) { + perror("FAIL - Could not listen: "); + return -1; + } + } + + return sock; +} + +int receive_udp(int sock) +{ + + char *buf; int ret = -1; int select_return; @@ -37,38 +98,6 @@ int receive_udp() buf = (char *) malloc(255); memset(buf, '\0', 255); - struct ip_address bind_addr; - if (!parse_ip(net_info.bind_ip, net_info.bind_port, &bind_addr)) { - fprintf(stderr, "FAIL - could not parse bind ip address\n"); - return -1; - } - - if ((sock = socket(bind_addr.family, SOCK_DGRAM, 0)) < 0) { - perror("FAIL - Socket error: "); - return(-1); - } - - const int enable = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0) - perror("FAIL - setsockopt(SO_REUSEADDR) failed"); - - if (bind_addr.family == AF_INET) { - local = convert_to_sockaddr_in(bind_addr); - if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) - { - perror("FAIL - Bind error: "); - return(-1); - } - } else { - local6 = convert_to_sockaddr_in6(bind_addr); - if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0) - { - printf("errno %d\n", errno); - perror("FAIL - Bind error: "); - return(-1); - } - } - FD_ZERO(&read_set); FD_SET(sock, &read_set); FD_ZERO(&err_set); @@ -77,39 +106,30 @@ int receive_udp() timeout.tv_usec = 0; select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout); - if (select_return < 0) - { + if (select_return < 0) { perror("FAIL - Select error: "); ret = -1; - } - - - - if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set))) - { - - if (recvfrom(sock, buf, 255, 0, (struct sockaddr *)0, (unsigned int *)0) >= 1) - { + } else if (select_return == 0) { + printf("FAIL - select timeout\n"); + } else if (select_return > 0 && FD_ISSET(sock, &read_set) && !FD_ISSET(sock, &err_set)) { + if (recvfrom(sock, buf, 255, 0, NULL, NULL) >= 1) { //printf("MESSAGE: %s\n", buf); ret = 0; - } - else - { + } else { printf("FAIL - recvfrom failed\n"); ret = -1; } } + free(buf); return(ret); } -int receive_tcp() +int receive_tcp(int sock) { - int sock, cli_sock; + int cli_sock; char *buf; - struct sockaddr_in local; - struct sockaddr_in6 local6; int ret = -1; int select_return; @@ -119,44 +139,6 @@ int receive_tcp() buf = (char *) malloc(255); memset(buf, '\0', 255); - struct ip_address bind_addr; - if (!parse_ip(net_info.bind_ip, net_info.bind_port, &bind_addr)) { - fprintf(stderr, "FAIL - could not parse bind ip address\n"); - return -1; - } - - if ((sock = socket(bind_addr.family, SOCK_STREAM, 0)) < 0) - { - perror("FAIL - Socket error:"); - return(-1); - } - - const int enable = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0) - perror("FAIL - setsockopt(SO_REUSEADDR) failed"); - - if (bind_addr.family == AF_INET) { - local = convert_to_sockaddr_in(bind_addr); - if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) - { - perror("FAIL - Bind error: "); - return(-1); - } - } else { - local6 = convert_to_sockaddr_in6(bind_addr); - if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0) - { - perror("FAIL - Bind error: "); - return(-1); - } - } - - if (listen(sock, 5) == -1) - { - perror("FAIL - Could not listen: "); - return(-1); - } - FD_ZERO(&read_set); FD_SET(sock, &read_set); FD_ZERO(&err_set); @@ -165,48 +147,33 @@ int receive_tcp() timeout.tv_usec = 0; select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout); - if (select_return < 0) - { + if (select_return < 0) { perror("FAIL - Select failed: "); ret = -1; - } - - if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set))) - { - if ((cli_sock = accept(sock, NULL, NULL)) < 0) - { + } else if (select_return == 0) { + printf("FAIL - select timeout\n"); + } else if (select_return > 0 && FD_ISSET(sock, &read_set) && !FD_ISSET(sock, &err_set)) { + if ((cli_sock = accept(sock, NULL, NULL)) < 0) { perror("FAIL - Accept failed: "); ret = -1; - } - else - { - if (recv(cli_sock, buf, 255, 0) >= 1) - { + } else { + if (recv(cli_sock, buf, 255, 0) >= 1) { //printf("MESSAGE: %s\n", buf); ret = 0; - } - else - { + } else { perror("FAIL - recv failure: "); ret = -1; } } } - else - { - perror("FAIL - There were select failures: "); - ret = -1; - } + free(buf); return(ret); } -int receive_icmp() +int receive_icmp(int sock) { - - int sock; char *buf; - struct sockaddr_in local; int ret = -1; int select_return; @@ -215,25 +182,6 @@ int receive_icmp() buf = (char *) malloc(255); memset(buf, '\0', 255); - if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)) < 0) - { - perror("FAIL - Socket error: "); - return(-1); - } - - const int enable = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &enable, sizeof(int)) < 0) - perror("FAIL - setsockopt(SO_REUSEADDR) failed"); - - local.sin_family = AF_INET; - local.sin_port = htons(atoi(net_info.bind_port)); - inet_aton(net_info.bind_ip, &local.sin_addr); - - if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) - { - perror("FAIL - Bind error: "); - return(-1); - } FD_ZERO(&read_set); FD_SET(sock, &read_set); @@ -243,28 +191,21 @@ int receive_icmp() timeout.tv_usec = 0; select_return = select(sock + 1, &read_set, NULL, &err_set, &timeout); - if (select_return < 0) - { + if (select_return < 0) { perror("FAIL - Select error: "); ret = -1; - } - - - - if ((select_return > 0) && (FD_ISSET(sock, &read_set)) && (!FD_ISSET(sock, &err_set))) - { - - if (recvfrom(sock, buf, 255, 0, (struct sockaddr *)0, (unsigned int *)0) >= 1) - { + } else if (select_return == 0) { + printf("FAIL - select timeout\n"); + } else if (select_return > 0 && FD_ISSET(sock, &read_set) && !FD_ISSET(sock, &err_set)) { + if (recvfrom(sock, buf, 255, 0, NULL, NULL) >= 1) { //printf("MESSAGE: %s\n", buf); ret = 0; - } - else - { + } else { printf("FAIL - recvfrom failed\n"); ret = -1; } } + free(buf); return(ret); @@ -302,7 +243,7 @@ int main(int argc, char *argv[]) {"protocol", required_argument, 0, 'p' }, {"timeout", required_argument, 0, 't' }, {"sender", required_argument, 0, 's' }, - {0, 0, 0, 0 } + {0, 0, 0, 0 } }; while ((opt = getopt_long(argc, argv,"i:o:r:e:p:t:s:", long_options, 0)) != -1) { @@ -321,6 +262,14 @@ int main(int argc, char *argv[]) break; case 'p': net_info.protocol = optarg; + if (strcmp(net_info.protocol, "udp") == 0) + net_info.prot = UDP; + else if (strcmp(net_info.protocol, "tcp") == 0) + net_info.prot = TCP; + else if (strcmp(net_info.protocol, "icmp") == 0) + net_info.prot = ICMP; + else + printf("FAIL - Unknown protocol.\n"); break; case 't': net_info.timeout = atoi(optarg); @@ -333,6 +282,13 @@ int main(int argc, char *argv[]) } } + /* get the server to bind/listen, so the child has something + * to connect to if it wins the race. */ + int sockfd = receive_bind(); + if (sockfd == -1) { + exit(1); + } + /* exec the sender */ pid = fork(); if (pid == -1) { @@ -357,22 +313,23 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - if (strcmp(net_info.protocol, "udp") == 0) - ret = receive_udp(net_info); - else if (strcmp(net_info.protocol, "tcp") == 0) - ret = receive_tcp(net_info); - else if (strcmp(net_info.protocol, "icmp") == 0) - ret = receive_icmp(net_info); - else - printf("FAIL - Unknown protocol.\n"); + switch(net_info.prot) { + case UDP: + ret = receive_udp(sockfd); + break; + case TCP: + ret = receive_tcp(sockfd); + break; + case ICMP: + ret = receive_icmp(sockfd); + break; + } - if (ret == -1) - { + if (ret == -1) { printf("FAIL - Receive message failed.\n"); exit(1); } printf("PASS\n"); - return 0; } diff --git a/tests/regression/apparmor/net_finegrained_snd.c b/tests/regression/apparmor/net_inet_snd.c similarity index 93% rename from tests/regression/apparmor/net_finegrained_snd.c rename to tests/regression/apparmor/net_inet_snd.c index b208f2a55..76bac0f35 100644 --- a/tests/regression/apparmor/net_finegrained_snd.c +++ b/tests/regression/apparmor/net_inet_snd.c @@ -12,7 +12,7 @@ #include #include #include -#include "net_finegrained.h" +#include "net_inet.h" struct connection_info { char *bind_ip; @@ -40,8 +40,7 @@ int send_udp(char *message) return -1; } - if ((sock = socket(bind_addr.family, SOCK_DGRAM, 0)) < 0) - { + if ((sock = socket(bind_addr.family, SOCK_DGRAM, 0)) < 0) { perror("FAIL SND - Could not open socket: "); return(-1); } @@ -53,15 +52,13 @@ int send_udp(char *message) if (bind_addr.family == AF_INET) { local = convert_to_sockaddr_in(bind_addr); - if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) - { + if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { perror("FAIL SND - Bind error: "); return(-1); } } else { local6 = convert_to_sockaddr_in6(bind_addr); - if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0) - { + if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0) { perror("FAIL SND - Bind error: "); return(-1); } @@ -70,22 +67,19 @@ int send_udp(char *message) if (remote_addr.family == AF_INET) { remote = convert_to_sockaddr_in(remote_addr); //printf("Sending \"%s\"\n", message); - if (sendto(sock, message, strlen(message), 0, (struct sockaddr *) &remote, sizeof(remote)) <= 0) - { + if (sendto(sock, message, strlen(message), 0, (struct sockaddr *) &remote, sizeof(remote)) <= 0) { perror("FAIL SND - Send failed: "); return(-1); } } else { remote6 = convert_to_sockaddr_in6(remote_addr); //printf("Sending \"%s\"\n", message); - if (sendto(sock, message, strlen(message), 0, (struct sockaddr *) &remote6, sizeof(remote6)) <= 0) - { + if (sendto(sock, message, strlen(message), 0, (struct sockaddr *) &remote6, sizeof(remote6)) <= 0) { perror("FAIL SND - Send failed: "); return(-1); } } - close(sock); return(0); @@ -121,15 +115,13 @@ int send_tcp(char *message) if (bind_addr.family == AF_INET) { local = convert_to_sockaddr_in(bind_addr); - if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) - { + if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { perror("FAIL SND - Bind error: "); return(-1); } } else { local6 = convert_to_sockaddr_in6(bind_addr); - if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0) - { + if (bind(sock, (struct sockaddr *) &local6, sizeof(local6)) < 0) { perror("FAIL SND - Bind error: "); return(-1); } @@ -138,24 +130,21 @@ int send_tcp(char *message) if (remote_addr.family == AF_INET) { remote = convert_to_sockaddr_in(remote_addr); //printf("Sending \"%s\"\n", message); - if (connect(sock, (struct sockaddr *) &remote, sizeof(remote)) < 0) - { + if (connect(sock, (struct sockaddr *) &remote, sizeof(remote)) < 0) { perror("FAIL SND - Could not connect: "); return(-1); } } else { remote6 = convert_to_sockaddr_in6(remote_addr); //printf("Sending \"%s\"\n", message); - if (connect(sock, (struct sockaddr *) &remote6, sizeof(remote6)) < 0) - { + if (connect(sock, (struct sockaddr *) &remote6, sizeof(remote6)) < 0) { perror("FAIL SND - Could not connect: "); return(-1); } } //printf("Sending \"%s\"\n", message); - if (send(sock, message, strlen(message), 0) <= 0) - { + if (send(sock, message, strlen(message), 0) <= 0) { perror("FAIL SND - Send failed: "); return(-1); } @@ -171,8 +160,7 @@ int send_icmp(char *message) char packetdata[sizeof(icmp_hdr) + 4]; - if ((sock = socket(AF_INET | AF_INET6, SOCK_DGRAM, IPPROTO_ICMP)) < 0) - { + if ((sock = socket(AF_INET | AF_INET6, SOCK_DGRAM, IPPROTO_ICMP)) < 0) { perror("FAIL SND - Could not open socket: "); return(-1); } @@ -199,8 +187,7 @@ int send_icmp(char *message) memcpy(packetdata, &icmp_hdr, sizeof(icmp_hdr)); memcpy(packetdata + sizeof(icmp_hdr), message, strlen(message)); - if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) - { + if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { perror("FAIL SND - Could not bind: "); return(-1); } @@ -208,8 +195,7 @@ int send_icmp(char *message) //printf("Sending \"%s\"\n", message); // Send the packet - if(sendto(sock, packetdata, sizeof(packetdata), 0, (struct sockaddr*) &remote, sizeof(remote)) < 0) - { + if(sendto(sock, packetdata, sizeof(packetdata), 0, (struct sockaddr*) &remote, sizeof(remote)) < 0) { perror("FAIL SND - Send failed: "); close(sock); return(-1); @@ -231,8 +217,7 @@ int main(int argc, char *argv[]) { int send_ret; - if (argc < 6) - { + if (argc < 6) { printf("Usage: %s bind_ip bind_port remote_ip remote_port proto\n", argv[0]); exit(1); } @@ -253,8 +238,7 @@ int main(int argc, char *argv[]) else printf("FAIL SND - Unknown protocol.\n"); - if (send_ret == -1) - { + if (send_ret == -1) { printf("FAIL SND - Send message failed.\n"); exit(1); }