diff options
author | ngie <ngie@FreeBSD.org> | 2015-12-29 19:56:26 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2015-12-29 19:56:26 +0000 |
commit | 48b72481dba08c5185c1dd6a70b82b326be43d6b (patch) | |
tree | bfa4f047c73b138c59732a37297737fa1ffd3e91 /tests | |
parent | f8c5cd12c37a92500da3f42f1d25bae9cc70e30a (diff) | |
parent | c0ae58548ada98f553239a091b8764ea9e1b474b (diff) | |
download | FreeBSD-src-48b72481dba08c5185c1dd6a70b82b326be43d6b.zip FreeBSD-src-48b72481dba08c5185c1dd6a70b82b326be43d6b.tar.gz |
MFhead @ r292618
Diffstat (limited to 'tests')
-rw-r--r-- | tests/sys/Makefile | 1 | ||||
-rw-r--r-- | tests/sys/aio/aio_kqueue_test.c | 37 | ||||
-rw-r--r-- | tests/sys/aio/lio_kqueue_test.c | 101 | ||||
-rwxr-xr-x | tests/sys/file/flock_test.sh | 5 | ||||
-rw-r--r-- | tests/sys/kern/pipe/pipe_overcommit1_test.c | 7 | ||||
-rw-r--r-- | tests/sys/kern/unix_seqpacket_test.c | 54 | ||||
-rw-r--r-- | tests/sys/mac/Makefile | 8 | ||||
-rw-r--r-- | tests/sys/mac/bsdextended/Makefile | 13 | ||||
-rw-r--r-- | tests/sys/mac/bsdextended/matches_test.sh | 353 | ||||
-rw-r--r-- | tests/sys/mac/bsdextended/ugidfw_test.c | 252 | ||||
-rw-r--r-- | tests/sys/mac/portacl/LICENSE | 27 | ||||
-rw-r--r-- | tests/sys/mac/portacl/Makefile | 16 | ||||
-rwxr-xr-x | tests/sys/mac/portacl/misc.sh | 106 | ||||
-rwxr-xr-x | tests/sys/mac/portacl/nobody_test.sh | 67 | ||||
-rwxr-xr-x | tests/sys/mac/portacl/root_test.sh | 51 |
15 files changed, 996 insertions, 102 deletions
diff --git a/tests/sys/Makefile b/tests/sys/Makefile index 3adf81e..702f664 100644 --- a/tests/sys/Makefile +++ b/tests/sys/Makefile @@ -10,6 +10,7 @@ TESTS_SUBDIRS+= fifo TESTS_SUBDIRS+= file TESTS_SUBDIRS+= kern TESTS_SUBDIRS+= kqueue +TESTS_SUBDIRS+= mac TESTS_SUBDIRS+= mqueue TESTS_SUBDIRS+= netinet TESTS_SUBDIRS+= opencrypto diff --git a/tests/sys/aio/aio_kqueue_test.c b/tests/sys/aio/aio_kqueue_test.c index 14e4729..97c2c38f 100644 --- a/tests/sys/aio/aio_kqueue_test.c +++ b/tests/sys/aio/aio_kqueue_test.c @@ -62,7 +62,10 @@ main (int argc, char *argv[]) struct kevent ke, kq_returned; struct timespec ts; char buffer[32768]; - int cancel, error, failed = 0, fd, kq, pending, result, run; +#ifdef DEBUG + int cancel, error; +#endif + int failed = 0, fd, kq, pending, result, run; int tmp_file = 0; unsigned i, j; @@ -96,19 +99,19 @@ main (int argc, char *argv[]) if (iocb[i] == NULL) err(1, "calloc"); } - - pending = 0; + + pending = 0; for (i = 0; i < nitems(iocb); i++) { pending++; iocb[i]->aio_nbytes = sizeof(buffer); iocb[i]->aio_buf = buffer; iocb[i]->aio_fildes = fd; iocb[i]->aio_offset = iocb[i]->aio_nbytes * i * run; - + iocb[i]->aio_sigevent.sigev_notify_kqueue = kq; iocb[i]->aio_sigevent.sigev_value.sival_ptr = iocb[i]; iocb[i]->aio_sigevent.sigev_notify = SIGEV_KEVENT; - + result = aio_write(iocb[i]); if (result != 0) { perror("aio_write"); @@ -133,7 +136,9 @@ main (int argc, char *argv[]) } } } +#ifdef DEBUG cancel = nitems(iocb) - pending; +#endif i = 0; while (pending) { @@ -144,34 +149,36 @@ main (int argc, char *argv[]) bzero(&kq_returned, sizeof(ke)); ts.tv_sec = 0; ts.tv_nsec = 1; - result = kevent(kq, NULL, 0, + result = kevent(kq, NULL, 0, &kq_returned, 1, &ts); +#ifdef DEBUG error = errno; +#endif if (result < 0) perror("kevent error: "); kq_iocb = kq_returned.udata; #ifdef DEBUG printf("kevent %d %d errno %d return.ident %p " - "return.data %p return.udata %p %p\n", - i, result, error, - kq_returned.ident, kq_returned.data, - kq_returned.udata, + "return.data %p return.udata %p %p\n", + i, result, error, + kq_returned.ident, kq_returned.data, + kq_returned.udata, kq_iocb); #endif - + if (kq_iocb) break; #ifdef DEBUG printf("Try again left %d out of %d %d\n", pending, nitems(iocb), cancel); #endif - } - + } + for (j = 0; j < nitems(iocb) && iocb[j] != kq_iocb; j++) ; #ifdef DEBUG printf("kq_iocb %p\n", kq_iocb); - + printf("Error Result for %d is %d pending %d\n", j, result, pending); #endif @@ -192,7 +199,7 @@ main (int argc, char *argv[]) iocb[j] = NULL; pending--; i++; - } + } for (i = 0; i < nitems(iocb); i++) free(iocb[i]); diff --git a/tests/sys/aio/lio_kqueue_test.c b/tests/sys/aio/lio_kqueue_test.c index 5cc87b3..e69b9c9 100644 --- a/tests/sys/aio/lio_kqueue_test.c +++ b/tests/sys/aio/lio_kqueue_test.c @@ -42,6 +42,7 @@ #include <sys/time.h> #include <aio.h> #include <fcntl.h> +#include <err.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -57,26 +58,26 @@ #define MAX_RUNS 300 int -main(int argc, char *argv[]){ +main(int argc, char *argv[]) +{ int fd; struct aiocb *iocb[MAX_IOCBS]; - struct aiocb **lio[LIO_MAX], **lio_element, **kq_lio; + struct aiocb **lio[LIO_MAX], **kq_lio; int i, result, run, error, j, k; char buffer[32768]; - int kq = kqueue(); + int kq; struct kevent ke, kq_returned; struct timespec ts; struct sigevent sig; time_t time1, time2; - char *file, pathname[sizeof(PATH_TEMPLATE)-1]; + char *file, pathname[sizeof(PATH_TEMPLATE)]; int tmp_file = 0, failed = 0; PLAIN_REQUIRE_KERNEL_MODULE("aio", 0); - if (kq < 0) { - perror("No kqeueue\n"); - exit(1); - } + kq = kqueue(); + if (kq < 0) + err(1, "kqeueue(2) failed"); if (argc == 1) { strcpy(pathname, PATH_TEMPLATE); @@ -87,34 +88,29 @@ main(int argc, char *argv[]){ file = argv[1]; fd = open(file, O_RDWR|O_CREAT, 0666); } - if (fd < 0){ - fprintf(stderr, "Can't open %s\n", argv[1]); - perror(""); - exit(1); - } + if (fd < 0) + err(1, "can't open %s", argv[1]); #ifdef DEBUG printf("Hello kq %d fd %d\n", kq, fd); #endif - for (run = 0; run < MAX_RUNS; run++){ + for (run = 0; run < MAX_RUNS; run++) { #ifdef DEBUG printf("Run %d\n", run); #endif for (j = 0; j < LIO_MAX; j++) { - lio[j] = (struct aiocb **) + lio[j] = malloc(sizeof(struct aiocb *) * MAX_IOCBS/LIO_MAX); - for(i = 0; i < MAX_IOCBS / LIO_MAX; i++) { + for (i = 0; i < MAX_IOCBS / LIO_MAX; i++) { k = (MAX_IOCBS / LIO_MAX * j) + i; - lio_element = lio[j]; - lio[j][i] = iocb[k] = (struct aiocb *) - malloc(sizeof(struct aiocb)); - bzero(iocb[k], sizeof(struct aiocb)); + lio[j][i] = iocb[k] = + calloc(1, sizeof(struct aiocb)); iocb[k]->aio_nbytes = sizeof(buffer); iocb[k]->aio_buf = buffer; iocb[k]->aio_fildes = fd; - iocb[k]->aio_offset - = iocb[k]->aio_nbytes * k * (run + 1); + iocb[k]->aio_offset + = iocb[k]->aio_nbytes * k * (run + 1); #ifdef DEBUG printf("hello iocb[k] %d\n", @@ -131,27 +127,26 @@ main(int argc, char *argv[]){ error = errno; time(&time2); #ifdef DEBUG - printf("Time %d %d %d result -> %d\n", + printf("Time %d %d %d result -> %d\n", time1, time2, time2-time1, result); #endif if (result != 0) { errno = error; - perror("list_listio"); - printf("FAIL: Result %d iteration %d\n",result, j); - exit(1); + err(1, "FAIL: Result %d iteration %d\n", + result, j); } #ifdef DEBUG printf("write %d is at %p\n", j, lio[j]); #endif } - for(i = 0; i < LIO_MAX; i++) { - for(j = LIO_MAX - 1; j >=0; j--) { + for (i = 0; i < LIO_MAX; i++) { + for (j = LIO_MAX - 1; j >=0; j--) { if (lio[j]) break; } - for(;;) { + for (;;) { bzero(&ke, sizeof(ke)); bzero(&kq_returned, sizeof(ke)); ts.tv_sec = 0; @@ -159,9 +154,9 @@ main(int argc, char *argv[]){ #ifdef DEBUG printf("FOO lio %d -> %p\n", j, lio[j]); #endif - EV_SET(&ke, (uintptr_t)lio[j], + EV_SET(&ke, (uintptr_t)lio[j], EVFILT_LIO, EV_ONESHOT, 0, 0, iocb[j]); - result = kevent(kq, NULL, 0, + result = kevent(kq, NULL, 0, &kq_returned, 1, &ts); error = errno; if (result < 0) { @@ -170,14 +165,14 @@ main(int argc, char *argv[]){ kq_lio = kq_returned.udata; #ifdef DEBUG printf("kevent %d %d errno %d return.ident %p " - "return.data %p return.udata %p %p\n", - i, result, error, - kq_returned.ident, kq_returned.data, - kq_returned.udata, + "return.data %p return.udata %p %p\n", + i, result, error, + kq_returned.ident, kq_returned.data, + kq_returned.udata, lio[j]); #endif - if(kq_lio) + if (kq_lio) break; #ifdef DEBUG printf("Try again\n"); @@ -189,25 +184,21 @@ main(int argc, char *argv[]){ #endif for (j = 0; j < LIO_MAX; j++) { - if (lio[j] == kq_lio) { + if (lio[j] == kq_lio) break; - } - } - if (j == LIO_MAX) { - printf("FAIL:\n"); - exit(1); } + if (j == LIO_MAX) + errx(1, "FAIL: "); #ifdef DEBUG printf("Error Result for %d is %d\n", j, result); #endif if (result < 0) { printf("FAIL: run %d, operation %d result %d \n", run, LIO_MAX - i -1, result); - failed = 1; - } else { + failed++; + } else printf("PASS: run %d, operation %d result %d \n", run, LIO_MAX - i -1, result); - } - for(k = 0; k < MAX_IOCBS / LIO_MAX; k++){ + for (k = 0; k < MAX_IOCBS / LIO_MAX; k++) { result = aio_return(kq_lio[k]); #ifdef DEBUG printf("Return Resulto for %d %d is %d\n", j, k, result); @@ -224,9 +215,8 @@ main(int argc, char *argv[]){ printf("\n"); #endif - for(k = 0; k < MAX_IOCBS / LIO_MAX; k++) { + for (k = 0; k < MAX_IOCBS / LIO_MAX; k++) free(lio[j][k]); - } free(lio[j]); lio[j] = NULL; } @@ -235,15 +225,12 @@ main(int argc, char *argv[]){ printf("Done\n"); #endif - if (tmp_file) { + if (tmp_file) unlink(pathname); - } - if (failed) { - printf("FAIL: Atleast one\n"); - exit(1); - } else { - printf("PASS: All\n"); - exit(0); - } + if (failed) + errx(1, "FAIL: %d testcases failed", failed); + else + errx(0, "PASS: All\n"); + } diff --git a/tests/sys/file/flock_test.sh b/tests/sys/file/flock_test.sh index f963cde..ead4ff1 100755 --- a/tests/sys/file/flock_test.sh +++ b/tests/sys/file/flock_test.sh @@ -43,10 +43,11 @@ for n in `seq 1 $last_testcase`; do todomsg=" # TODO: racy testcase" fi - $(dirname $0)/flock_helper . $n | grep -q SUCCEED - if [ $? -eq 0 ]; then + output=$($(dirname $0)/flock_helper . $n) + if echo "$output" | grep -q SUCCEED; then echo "ok $n$todomsg" else echo "not ok $n$todomsg" + echo "$output" >&2 fi done diff --git a/tests/sys/kern/pipe/pipe_overcommit1_test.c b/tests/sys/kern/pipe/pipe_overcommit1_test.c index f8f881d..4e40be7 100644 --- a/tests/sys/kern/pipe/pipe_overcommit1_test.c +++ b/tests/sys/kern/pipe/pipe_overcommit1_test.c @@ -40,12 +40,11 @@ int main(void) { - int pipes[10000], returnval; + int pipes[10000]; unsigned int i; - for (i = 0; i < nitems(pipes); i++) { - returnval = pipe(&pipes[i]); - } + for (i = 0; i < nitems(pipes); i++) + (void)pipe(&pipes[i]); printf("PASS\n"); exit(0); diff --git a/tests/sys/kern/unix_seqpacket_test.c b/tests/sys/kern/unix_seqpacket_test.c index 986b70e..7305ab3 100644 --- a/tests/sys/kern/unix_seqpacket_test.c +++ b/tests/sys/kern/unix_seqpacket_test.c @@ -47,7 +47,7 @@ static void do_socketpair(int *sv) { int s; - + s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); ATF_REQUIRE_EQ(0, s); ATF_REQUIRE(sv[0] >= 0); @@ -59,7 +59,7 @@ static void do_socketpair_nonblocking(int *sv) { int s; - + s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); ATF_REQUIRE_EQ(0, s); ATF_REQUIRE(sv[0] >= 0); @@ -69,7 +69,7 @@ do_socketpair_nonblocking(int *sv) ATF_REQUIRE(-1 != fcntl(sv[1], F_SETFL, O_NONBLOCK)); } -/* +/* * Returns a pair of sockets made the hard way: bind, listen, connect & accept * @return const char* The path to the socket */ @@ -100,7 +100,7 @@ mk_pair_of_sockets(int *sv) perror("connect"); atf_tc_fail("connect(2) failed"); } - + /* Accept it */ s1 = accept(s, NULL, NULL); if (s1 == -1) { @@ -239,7 +239,7 @@ test_pipe_simulator(size_t sndbufsize, size_t rcvbufsize) memset(sndbuf, num_sent, pktsize); ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); if (ssize < 0) { - /* + /* * XXX: This is bug-compatible with the kernel. * The kernel returns EMSGSIZE when it should * return EAGAIN @@ -275,7 +275,7 @@ test_pipe_simulator(size_t sndbufsize, size_t rcvbufsize) pktsize, rsize); memset(comparebuf, num_received, pktsize); ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf, - pktsize), + pktsize), "Received data miscompare"); num_received++; } @@ -333,7 +333,7 @@ test_pipe_reader(void* args) "expected %zd=send(...) but got %zd", td->pktsize, rsize); d = memcmp(comparebuf, rcvbuf, td->pktsize); - ATF_CHECK_EQ_MSG(0, d, + ATF_CHECK_EQ_MSG(0, d, "Received data miscompare on packet %d", i); } return (0); @@ -369,7 +369,7 @@ test_pipe(size_t sndbufsize, size_t rcvbufsize) reader_data.so = sv[1]; ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer, (void*)&writer_data)); - /* + /* * Give the writer time to start writing, and hopefully block, before * starting the reader. This increases the likelihood of the test case * failing due to PR kern/185812 @@ -561,7 +561,7 @@ ATF_TC_BODY(resize_buffers, tc) ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); printf("After changing SNDBUF | %7d | %7d |\n", xs, xr); - + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){ perror("setsockopt"); atf_tc_fail("setsockopt(SO_RCVBUF) failed"); @@ -671,7 +671,9 @@ ATF_TC_BODY(send_recv, tc) ATF_TC_WITHOUT_HEAD(sendto_recvfrom); ATF_TC_BODY(sendto_recvfrom, tc) { +#ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS const char* path; +#endif struct sockaddr_storage from; int sv[2]; const int bufsize = 64; @@ -682,7 +684,10 @@ ATF_TC_BODY(sendto_recvfrom, tc) socklen_t fromlen; /* setup the socket pair */ - path = mk_pair_of_sockets(sv); +#ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS + path = +#endif + mk_pair_of_sockets(sv); /* send and receive a small packet */ datalen = strlen(data) + 1; /* +1 for the null */ @@ -703,19 +708,21 @@ ATF_TC_BODY(sendto_recvfrom, tc) } ATF_CHECK_EQ(datalen, rsize); - /* +#ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS + /* * FreeBSD does not currently provide the source address for SEQ_PACKET * AF_UNIX sockets, and POSIX does not require it, so these two checks * are disabled. If FreeBSD gains that feature in the future, then * these checks may be reenabled */ - /* ATF_CHECK_EQ(PF_LOCAL, from.ss_family); */ - /* ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); */ + ATF_CHECK_EQ(PF_LOCAL, from.ss_family); + ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); +#endif close(sv[0]); close(sv[1]); } -/* +/* * send(2) and recv(2) a single short record with sockets created the * traditional way, involving bind, listen, connect, and accept */ @@ -795,7 +802,6 @@ ATF_TC_BODY(shutdown_send_sigpipe, tc) /* ATF's isolation mechanisms will guarantee uniqueness of this file */ const char *path = "sock"; const char *data = "data"; - ssize_t ssize; int s, err, s2; s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); @@ -820,7 +826,7 @@ ATF_TC_BODY(shutdown_send_sigpipe, tc) ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); - ssize = send(s2, data, sizeof(data), MSG_EOR); + (void)send(s2, data, sizeof(data), MSG_EOR); ATF_CHECK_EQ(1, got_sigpipe); close(s); close(s2); @@ -861,7 +867,7 @@ ATF_TC_BODY(send_recv_nonblocking, tc) close(sv[1]); } -/* +/* * We should get EMSGSIZE if we try to send a message larger than the socket * buffer, with blocking sockets */ @@ -890,7 +896,7 @@ ATF_TC_BODY(emsgsize, tc) close(sv[1]); } -/* +/* * We should get EMSGSIZE if we try to send a message larger than the socket * buffer, with nonblocking sockets */ @@ -920,7 +926,7 @@ ATF_TC_BODY(emsgsize_nonblocking, tc) } -/* +/* * We should get EAGAIN if we try to send a message larger than the socket * buffer, with nonblocking sockets. Test with several different sockbuf sizes */ @@ -946,7 +952,7 @@ ATF_TC_BODY(eagain_128k_128k, tc) } -/* +/* * nonblocking send(2) and recv(2) of several records, which should collectively * fill up the send buffer but not the receive buffer */ @@ -971,7 +977,7 @@ ATF_TC_BODY(rcvbuf_oversized, tc) ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(rcvbufsize))); - /* + /* * Send and receive packets that are collectively greater than the send * buffer, but less than the receive buffer */ @@ -999,7 +1005,7 @@ ATF_TC_BODY(rcvbuf_oversized, tc) "expected %zd=send(...) but got %zd", pktsize, rsize); /* Verify the contents */ - ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), + ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), "Received data miscompare"); } @@ -1011,7 +1017,7 @@ ATF_TC_BODY(rcvbuf_oversized, tc) close(sv[1]); } -/* +/* * Simulate the behavior of a blocking pipe. The sender will send until his * buffer fills up, then we'll simulate a scheduler switch that will allow the * receiver to read until his buffer empties. Repeat the process until the @@ -1042,7 +1048,7 @@ ATF_TC_BODY(pipe_simulator_128k_128k, tc) test_pipe_simulator(131072, 131072); } -/* +/* * Test blocking I/O by passing data between two threads. The total amount of * data will be >> buffer size to force blocking. Repeat the test with multiple * send and receive buffer sizes diff --git a/tests/sys/mac/Makefile b/tests/sys/mac/Makefile new file mode 100644 index 0000000..ae2c491 --- /dev/null +++ b/tests/sys/mac/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/sys/mac + +TESTS_SUBDIRS+= bsdextended +TESTS_SUBDIRS+= portacl + +.include <bsd.test.mk> diff --git a/tests/sys/mac/bsdextended/Makefile b/tests/sys/mac/bsdextended/Makefile new file mode 100644 index 0000000..9d0b6f6 --- /dev/null +++ b/tests/sys/mac/bsdextended/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/sys/mac/bsdextended + +TAP_TESTS_C+= ugidfw_test +TAP_TESTS_SH+= matches_test + +LIBADD.ugidfw_test+= ugidfw + +TEST_METADATA.matches_test+= required_user="root" +TEST_METADATA.ugidfw_test+= required_user="root" + +.include <bsd.test.mk> diff --git a/tests/sys/mac/bsdextended/matches_test.sh b/tests/sys/mac/bsdextended/matches_test.sh new file mode 100644 index 0000000..5aff413 --- /dev/null +++ b/tests/sys/mac/bsdextended/matches_test.sh @@ -0,0 +1,353 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +uidrange="60000:100000" +gidrange="60000:100000" +uidinrange="nobody" +uidoutrange="daemon" +gidinrange="nobody" # We expect $uidinrange in this group +gidoutrange="daemon" # We expect $uidinrange in this group + +test_num=1 +pass() +{ + echo "ok $test_num # $@" + : $(( test_num += 1 )) +} + +fail() +{ + echo "not ok $test_num # $@" + : $(( test_num += 1 )) +} + +# +# Setup +# + +: ${TMPDIR=/tmp} +if [ $(id -u) -ne 0 ]; then + echo "1..0 # SKIP test must be run as root" + exit 0 +fi +if ! sysctl -N security.mac.bsdextended >/dev/null 2>&1; then + echo "1..0 # SKIP mac_bsdextended(4) support isn't available" + exit 0 +fi +if ! playground=$(mktemp -d $TMPDIR/tmp.XXXXXXX); then + echo "1..0 # SKIP failed to create temporary directory" + exit 0 +fi +trap "rmdir $playground" EXIT INT TERM +if ! mdmfs -s 25m md $playground; then + echo "1..0 # SKIP failed to mount md device" + exit 0 +fi +chmod a+rwx $playground +md_device=$(mount -p | grep "$playground" | awk '{ gsub(/^\/dev\//, "", $1); print $1 }') +trap "umount -f $playground; mdconfig -d -u $md_device; rmdir $playground" EXIT INT TERM +if [ -z "$md_device" ]; then + mount -p | grep $playground + echo "1..0 # SKIP md device not properly attached to the system" +fi + +ugidfw remove 1 + +file1=$playground/test-$uidinrange +file2=$playground/test-$uidoutrange +cat > $playground/test-script.sh <<'EOF' +#!/bin/sh +: > $1 +EOF +if [ $? -ne 0 ]; then + echo "1..0 # SKIP failed to create test script" + exit 0 +fi +echo "1..30" + +command1="sh $playground/test-script.sh $file1" +command2="sh $playground/test-script.sh $file2" + +desc="$uidinrange file" +if su -m $uidinrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +chown "$uidinrange":"$gidinrange" $file1 +chmod a+w $file1 + +desc="$uidoutrange file" +if $command2; then + pass $desc +else + fail $desc +fi + +chown "$uidoutrange":"$gidoutrange" $file2 +chmod a+w $file2 + +# +# No rules +# +desc="no rules $uidinrange" +if su -fm $uidinrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +desc="no rules $uidoutrange" +if su -fm $uidoutrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +# +# Subject Match on uid +# +ugidfw set 1 subject uid $uidrange object mode rasx +desc="subject uid in range" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +desc="subject uid out range" +if su -fm $uidoutrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +# +# Subject Match on gid +# +ugidfw set 1 subject gid $gidrange object mode rasx + +desc="subject gid in range" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +desc="subject gid out range" +if su -fm $uidoutrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +# +# Subject Match on jail +# +rm -f $playground/test-jail + +desc="subject matching jailid" +jailid=`jail -i / localhost 127.0.0.1 /usr/sbin/daemon -f /bin/sh -c "(sleep 5; touch $playground/test-jail) &"` +ugidfw set 1 subject jailid $jailid object mode rasx +sleep 10 + +if [ -f $playground/test-jail ]; then + fail "TODO $desc: this testcase fails (see bug # 205481)" +else + pass $desc +fi + +rm -f $playground/test-jail +desc="subject nonmatching jailid" +jailid=`jail -i / localhost 127.0.0.1 /usr/sbin/daemon -f /bin/sh -c "(sleep 5; touch $playground/test-jail) &"` +sleep 10 +if [ -f $playground/test-jail ]; then + pass $desc +else + fail $desc +fi + +# +# Object uid +# +ugidfw set 1 subject object uid $uidrange mode rasx + +desc="object uid in range" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +desc="object uid out range" +if su -fm $uidinrange -c "$command2"; then + pass $desc +else + fail $desc +fi +ugidfw set 1 subject object uid $uidrange mode rasx + +desc="object uid in range (different subject)" +if su -fm $uidoutrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +desc="object uid out range (different subject)" +if su -fm $uidoutrange -c "$command2"; then + pass $desc +else + fail $desc +fi + +# +# Object gid +# +ugidfw set 1 subject object gid $uidrange mode rasx + +desc="object gid in range" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +desc="object gid out range" +if su -fm $uidinrange -c "$command2"; then + pass $desc +else + fail $desc +fi +desc="object gid in range (different subject)" +if su -fm $uidoutrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +desc="object gid out range (different subject)" +if su -fm $uidoutrange -c "$command2"; then + pass $desc +else + fail $desc +fi + +# +# Object filesys +# +ugidfw set 1 subject uid $uidrange object filesys / mode rasx +desc="object out of filesys" +if su -fm $uidinrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +ugidfw set 1 subject uid $uidrange object filesys $playground mode rasx +desc="object in filesys" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +# +# Object suid +# +ugidfw set 1 subject uid $uidrange object suid mode rasx +desc="object notsuid" +if su -fm $uidinrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +chmod u+s $file1 +desc="object suid" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi +chmod u-s $file1 + +# +# Object sgid +# +ugidfw set 1 subject uid $uidrange object sgid mode rasx +desc="object notsgid" +if su -fm $uidinrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +chmod g+s $file1 +desc="object sgid" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi +chmod g-s $file1 + +# +# Object uid matches subject +# +ugidfw set 1 subject uid $uidrange object uid_of_subject mode rasx + +desc="object uid notmatches subject" +if su -fm $uidinrange -c "$command2"; then + pass $desc +else + fail $desc +fi + +desc="object uid matches subject" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +# +# Object gid matches subject +# +ugidfw set 1 subject uid $uidrange object gid_of_subject mode rasx + +desc="object gid notmatches subject" +if su -fm $uidinrange -c "$command2"; then + pass $desc +else + fail $desc +fi + +desc="object gid matches subject" +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi + +# +# Object type +# +desc="object not type" +ugidfw set 1 subject uid $uidrange object type dbclsp mode rasx +if su -fm $uidinrange -c "$command1"; then + pass $desc +else + fail $desc +fi + +desc="object type" +ugidfw set 1 subject uid $uidrange object type r mode rasx +if su -fm $uidinrange -c "$command1"; then + fail $desc +else + pass $desc +fi diff --git a/tests/sys/mac/bsdextended/ugidfw_test.c b/tests/sys/mac/bsdextended/ugidfw_test.c new file mode 100644 index 0000000..aab8553 --- /dev/null +++ b/tests/sys/mac/bsdextended/ugidfw_test.c @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2005 McAfee, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/mac.h> +#include <sys/mount.h> + +#include <security/mac_bsdextended/mac_bsdextended.h> + +#include <err.h> +#include <errno.h> +#include <grp.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ugidfw.h> +#include <unistd.h> + +/* + * Starting point for a regression test for mac_bsdextended(4) and the + * supporting libugidfw(3). + */ + +/* + * This section of the regression test passes some test cases through the + * rule<->string routines to confirm they work approximately as desired. + */ + +/* + * List of users and groups we must check exists before we can begin, since + * they are used in the string test rules. We use users and groups that will + * always exist in a default install used for regression testing. + */ +static const char *test_users[] = { + "root", + "daemon", + "operator", + "bin", +}; + +static const char *test_groups[] = { + "wheel", + "daemon", + "operator", + "bin", +}; + +int test_num; + +/* + * List of test strings that must go in (and come out) of libugidfw intact. + */ +static const char *test_strings[] = { + /* Variations on subject and object uids. */ + "subject uid root object uid root mode n", + "subject uid root object uid daemon mode n", + "subject uid daemon object uid root mode n", + "subject uid daemon object uid daemon mode n", + /* Variations on mode. */ + "subject uid root object uid root mode a", + "subject uid root object uid root mode r", + "subject uid root object uid root mode s", + "subject uid root object uid root mode w", + "subject uid root object uid root mode x", + "subject uid root object uid root mode arswx", + /* Variations on subject and object gids. */ + "subject gid wheel object gid wheel mode n", + "subject gid wheel object gid daemon mode n", + "subject gid daemon object gid wheel mode n", + "subject gid daemon object gid daemon mode n", + /* Subject uids and subject gids. */ + "subject uid bin gid daemon object uid operator gid wheel mode n", + /* Not */ + "subject not uid operator object uid bin mode n", + "subject uid bin object not uid operator mode n", + "subject not uid daemon object not uid operator mode n", + /* Ranges */ + "subject uid root:operator object gid wheel:bin mode n", + /* Jail ID */ + "subject jailid 1 object uid root mode n", + /* Filesys */ + "subject uid root object filesys / mode n", + "subject uid root object filesys /dev mode n", + /* S/UGID */ + "subject not uid root object sgid mode n", + "subject not uid root object sgid mode n", + /* Matching uid/gid */ + "subject not uid root:operator object not uid_of_subject mode n", + "subject not gid wheel:bin object not gid_of_subject mode n", + /* Object types */ + "subject uid root object type a mode a", + "subject uid root object type r mode a", + "subject uid root object type d mode a", + "subject uid root object type b mode a", + "subject uid root object type c mode a", + "subject uid root object type l mode a", + "subject uid root object type s mode a", + "subject uid root object type rbc mode a", + "subject uid root object type dls mode a", + /* Empty rules always match */ + "subject object mode a", + /* Partial negations */ + "subject ! uid root object mode n", + "subject ! gid wheel object mode n", + "subject ! jailid 2 object mode n", + "subject object ! uid root mode n", + "subject object ! gid wheel mode n", + "subject object ! filesys / mode n", + "subject object ! suid mode n", + "subject object ! sgid mode n", + "subject object ! uid_of_subject mode n", + "subject object ! gid_of_subject mode n", + "subject object ! type d mode n", + /* All out nonsense */ + "subject uid root ! gid wheel:bin ! jailid 1 " + "object ! uid root:daemon gid daemon filesys / suid sgid uid_of_subject gid_of_subject ! type r " + "mode rsx", +}; + +static void +test_libugidfw_strings(void) +{ + struct mac_bsdextended_rule rule; + char errorstr[256]; + char rulestr[256]; + int error, i; + + for (i = 0; i < nitems(test_users); i++, test_num++) { + if (getpwnam(test_users[i]) == NULL) + printf("not ok %d # test_libugidfw_strings: getpwnam(%s) " + "failed: %s\n", test_num, test_users[i], strerror(errno)); + else + printf("ok %d\n", test_num); + } + + for (i = 0; i < nitems(test_groups); i++, test_num++) { + if (getgrnam(test_groups[i]) == NULL) + printf("not ok %d # test_libugidfw_strings: getgrnam(%s) " + "failed: %s\n", test_num, test_groups[i], strerror(errno)); + else + printf("ok %d\n", test_num); + } + + for (i = 0; i < nitems(test_strings); i++) { + error = bsde_parse_rule_string(test_strings[i], &rule, + sizeof(errorstr), errorstr); + if (error == -1) + printf("not ok %d # bsde_parse_rule_string: '%s' (%d) " + "failed: %s\n", test_num, test_strings[i], i, errorstr); + else + printf("ok %d\n", test_num); + test_num++; + + error = bsde_rule_to_string(&rule, rulestr, sizeof(rulestr)); + if (error < 0) + printf("not ok %d # bsde_rule_to_string: rule for '%s' " + "returned %d\n", test_num, test_strings[i], error); + else + printf("ok %d\n", test_num); + test_num++; + + if (strcmp(test_strings[i], rulestr) != 0) + printf("not ok %d # test_libugidfw: '%s' in, '%s' " + "out\n", test_num, test_strings[i], rulestr); + else + printf("ok %d\n", test_num); + test_num++; + } +} + +int +main(void) +{ + char errorstr[256]; + int count, slots; + + test_num = 1; + + /* Print an error if a non-root user attemps to run the tests. */ + if (getuid() != 0) { + printf("1..0 # SKIP you must be root\n"); + return (0); + } + + switch (mac_is_present("bsdextended")) { + case -1: + printf("1..0 # SKIP mac_is_present failed: %s\n", + strerror(errno)); + return (0); + case 1: + break; + case 0: + default: + printf("1..0 # SKIP mac_bsdextended not loaded\n"); + return (0); + } + + printf("1..%lu\n", nitems(test_users) + nitems(test_groups) + + 3 * nitems(test_strings) + 2); + + test_libugidfw_strings(); + + /* + * Some simple up-front checks to see if we're able to query the + * policy for basic state. We want the rule count to be 0 before + * starting, but "slots" is a property of prior runs and so we ignore + * the return value. + */ + count = bsde_get_rule_count(sizeof(errorstr), errorstr); + if (count == -1) + printf("not ok %d # bsde_get_rule_count: %s\n", test_num, + errorstr); + else + printf("ok %d\n", test_num); + + test_num++; + + slots = bsde_get_rule_slots(sizeof(errorstr), errorstr); + if (slots == -1) + printf("not ok %d # bsde_get_rule_slots: %s\n", test_num, + errorstr); + else + printf("ok %d\n", test_num); + + return (0); +} diff --git a/tests/sys/mac/portacl/LICENSE b/tests/sys/mac/portacl/LICENSE new file mode 100644 index 0000000..c95c149 --- /dev/null +++ b/tests/sys/mac/portacl/LICENSE @@ -0,0 +1,27 @@ +$FreeBSD$ + +License for all mac_portacl regression tests: + +Copyright (c) 2009 Pawel Jakub Dawidek <pjd@FreeBSD.org> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/tests/sys/mac/portacl/Makefile b/tests/sys/mac/portacl/Makefile new file mode 100644 index 0000000..129d486 --- /dev/null +++ b/tests/sys/mac/portacl/Makefile @@ -0,0 +1,16 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/sys/mac/portacl +BINDIR= ${TESTSDIR} + +FILES+= misc.sh + +TAP_TESTS_SH+= nobody_test +TAP_TESTS_SH+= root_test + +.for t in ${TAP_TESTS_SH} +TEST_METADATA.$t+= required_user="root" +TEST_METADATA.$t+= timeout="450" +.endfor + +.include <bsd.test.mk> diff --git a/tests/sys/mac/portacl/misc.sh b/tests/sys/mac/portacl/misc.sh new file mode 100755 index 0000000..5a9e67b --- /dev/null +++ b/tests/sys/mac/portacl/misc.sh @@ -0,0 +1,106 @@ +#!/bin/sh +# $FreeBSD$ + +sysctl security.mac.portacl >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "1..0 # SKIP MAC_PORTACL is unavailable." + exit 0 +fi +if [ $(id -u) -ne 0 ]; then + echo "1..0 # SKIP testcases must be run as root" + exit 0 +fi + +ntest=1 + +check_bind() { + local host idtype name proto port udpflag + + host="127.0.0.1" + + idtype=${1} + name=${2} + proto=${3} + port=${4} + + [ "${proto}" = "udp" ] && udpflag="-u" + + out=$( + case "${idtype}" in + uid|gid) + ( echo -n | su -m ${name} -c "nc ${udpflag} -l -w 10 $host $port" 2>&1 ) & + ;; + jail) + kill $$ + ;; + *) + kill $$ + esac + sleep 0.3 + echo | nc ${udpflag} -w 10 $host $port >/dev/null 2>&1 + wait + ) + case "${out}" in + "nc: Permission denied"*|"nc: Operation not permitted"*) + echo fl + ;; + "") + echo ok + ;; + *) + echo ${out} + ;; + esac +} + +bind_test() { + local expect_without_rule expect_with_rule idtype name proto port + + expect_without_rule=${1} + expect_with_rule=${2} + idtype=${3} + name=${4} + proto=${5} + port=${6} + + sysctl security.mac.portacl.rules= >/dev/null + out=$(check_bind ${idtype} ${name} ${proto} ${port}) + if [ "${out}" = "${expect_without_rule}" ]; then + echo "ok ${ntest}" + elif [ "${out}" = "ok" -o "${out}" = "fl" ]; then + echo "not ok ${ntest} # '${out}' != '${expect_without_rule}'" + else + echo "not ok ${ntest} # unexpected output: '${out}'" + fi + : $(( ntest += 1 )) + + if [ "${idtype}" = "uid" ]; then + idstr=$(id -u ${name}) + elif [ "${idtype}" = "gid" ]; then + idstr=$(id -g ${name}) + else + idstr=${name} + fi + sysctl security.mac.portacl.rules=${idtype}:${idstr}:${proto}:${port} >/dev/null + out=$(check_bind ${idtype} ${name} ${proto} ${port}) + if [ "${out}" = "${expect_with_rule}" ]; then + echo "ok ${ntest}" + elif [ "${out}" = "ok" -o "${out}" = "fl" ]; then + echo "not ok ${ntest} # '${out}' != '${expect_with_rule}'" + else + echo "not ok ${ntest} # unexpected output: '${out}'" + fi + : $(( ntest += 1 )) + + sysctl security.mac.portacl.rules= >/dev/null +} + +reserved_high=$(sysctl -n net.inet.ip.portrange.reservedhigh) +suser_exempt=$(sysctl -n security.mac.portacl.suser_exempt) +port_high=$(sysctl -n security.mac.portacl.port_high) + +restore_settings() { + sysctl -n net.inet.ip.portrange.reservedhigh=${reserved_high} >/dev/null + sysctl -n security.mac.portacl.suser_exempt=${suser_exempt} >/dev/null + sysctl -n security.mac.portacl.port_high=${port_high} >/dev/null +} diff --git a/tests/sys/mac/portacl/nobody_test.sh b/tests/sys/mac/portacl/nobody_test.sh new file mode 100755 index 0000000..7d8dbd6 --- /dev/null +++ b/tests/sys/mac/portacl/nobody_test.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# $FreeBSD$ + +dir=`dirname $0` +. ${dir}/misc.sh + +echo "1..64" + +# security.mac.portacl.suser_exempt value doesn't affect unprivileged users +# behaviour. +# mac_portacl has no impact on ports <= net.inet.ip.portrange.reservedhigh. + +trap restore_settings EXIT INT TERM + +sysctl security.mac.portacl.suser_exempt=1 >/dev/null +sysctl net.inet.ip.portrange.reservedhigh=78 >/dev/null + +bind_test fl fl uid nobody tcp 77 +bind_test ok ok uid nobody tcp 7777 +bind_test fl fl uid nobody udp 77 +bind_test ok ok uid nobody udp 7777 + +bind_test fl fl gid nobody tcp 77 +bind_test ok ok gid nobody tcp 7777 +bind_test fl fl gid nobody udp 77 +bind_test ok ok gid nobody udp 7777 + +sysctl security.mac.portacl.suser_exempt=0 >/dev/null + +bind_test fl fl uid nobody tcp 77 +bind_test ok ok uid nobody tcp 7777 +bind_test fl fl uid nobody udp 77 +bind_test ok ok uid nobody udp 7777 + +bind_test fl fl gid nobody tcp 77 +bind_test ok ok gid nobody tcp 7777 +bind_test fl fl gid nobody udp 77 +bind_test ok ok gid nobody udp 7777 + +# Verify if security.mac.portacl.port_high works. + +sysctl security.mac.portacl.port_high=7778 >/dev/null + +bind_test fl fl uid nobody tcp 77 +bind_test fl ok uid nobody tcp 7777 +bind_test fl fl uid nobody udp 77 +bind_test fl ok uid nobody udp 7777 + +bind_test fl fl gid nobody tcp 77 +bind_test fl ok gid nobody tcp 7777 +bind_test fl fl gid nobody udp 77 +bind_test fl ok gid nobody udp 7777 + +# Verify if mac_portacl rules work. + +sysctl net.inet.ip.portrange.reservedhigh=76 >/dev/null +sysctl security.mac.portacl.port_high=7776 >/dev/null + +bind_test fl ok uid nobody tcp 77 +bind_test ok ok uid nobody tcp 7777 +bind_test fl ok uid nobody udp 77 +bind_test ok ok uid nobody udp 7777 + +bind_test fl ok gid nobody tcp 77 +bind_test ok ok gid nobody tcp 7777 +bind_test fl ok gid nobody udp 77 +bind_test ok ok gid nobody udp 7777 diff --git a/tests/sys/mac/portacl/root_test.sh b/tests/sys/mac/portacl/root_test.sh new file mode 100755 index 0000000..9ed452f --- /dev/null +++ b/tests/sys/mac/portacl/root_test.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# $FreeBSD$ + +dir=`dirname $0` +. ${dir}/misc.sh + +echo "1..48" + +# Verify if security.mac.portacl.suser_exempt=1 really exempts super-user. + +trap restore_settings EXIT INT TERM + +sysctl security.mac.portacl.suser_exempt=1 >/dev/null + +bind_test ok ok uid root tcp 77 +bind_test ok ok uid root tcp 7777 +bind_test ok ok uid root udp 77 +bind_test ok ok uid root udp 7777 + +bind_test ok ok gid root tcp 77 +bind_test ok ok gid root tcp 7777 +bind_test ok ok gid root udp 77 +bind_test ok ok gid root udp 7777 + +# Verify if security.mac.portacl.suser_exempt=0 really doesn't exempt super-user. + +sysctl security.mac.portacl.suser_exempt=0 >/dev/null + +bind_test fl ok uid root tcp 77 +bind_test ok ok uid root tcp 7777 +bind_test fl ok uid root udp 77 +bind_test ok ok uid root udp 7777 + +bind_test fl ok gid root tcp 77 +bind_test ok ok gid root tcp 7777 +bind_test fl ok gid root udp 77 +bind_test ok ok gid root udp 7777 + +# Verify if security.mac.portacl.port_high works for super-user. + +sysctl security.mac.portacl.port_high=7778 >/dev/null + +bind_test fl ok uid root tcp 77 +bind_test fl ok uid root tcp 7777 +bind_test fl ok uid root udp 77 +bind_test fl ok uid root udp 7777 + +bind_test fl ok gid root tcp 77 +bind_test fl ok gid root tcp 7777 +bind_test fl ok gid root udp 77 +bind_test fl ok gid root udp 7777 |