Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Dec 2015 21:24:03 +0000 (UTC)
From:      Garrett Cooper <ngie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r292570 - in head: etc/mtree tests/sys tests/sys/mac tests/sys/mac/bsdextended tests/sys/mac/portacl tools/regression/mac
Message-ID:  <201512212124.tBLLO3l8011715@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ngie
Date: Mon Dec 21 21:24:03 2015
New Revision: 292570
URL: https://svnweb.freebsd.org/changeset/base/292570

Log:
  Integrate tools/regression/mac/mac_bsdextended and
  tools/regression/mac/mac_portacl into the FreeBSD test suite as
  tests/sys/mac/bsdextended and tests/sys/mac/portacl, respectively
  
  MFC after: 1 month
  Sponsored by: EMC / Isilon Storage Division

Added:
  head/tests/sys/mac/
  head/tests/sys/mac/Makefile   (contents, props changed)
  head/tests/sys/mac/bsdextended/
  head/tests/sys/mac/bsdextended/Makefile   (contents, props changed)
  head/tests/sys/mac/bsdextended/matches_test.sh
     - copied unchanged from r292569, head/tools/regression/mac/mac_bsdextended/test_matches.sh
  head/tests/sys/mac/bsdextended/ugidfw_test.c
     - copied unchanged from r292569, head/tools/regression/mac/mac_bsdextended/test_ugidfw.c
  head/tests/sys/mac/portacl/
  head/tests/sys/mac/portacl/LICENSE
     - copied unchanged from r292569, head/tools/regression/mac/mac_portacl/LICENSE
  head/tests/sys/mac/portacl/Makefile   (contents, props changed)
  head/tests/sys/mac/portacl/misc.sh
     - copied unchanged from r292569, head/tools/regression/mac/mac_portacl/misc.sh
  head/tests/sys/mac/portacl/nobody_test.sh
     - copied unchanged from r292569, head/tools/regression/mac/mac_portacl/nobody.t
  head/tests/sys/mac/portacl/root_test.sh
     - copied unchanged from r292569, head/tools/regression/mac/mac_portacl/root.t
Deleted:
  head/tools/regression/mac/
Modified:
  head/etc/mtree/BSD.tests.dist
  head/tests/sys/Makefile

Modified: head/etc/mtree/BSD.tests.dist
==============================================================================
--- head/etc/mtree/BSD.tests.dist	Mon Dec 21 21:15:23 2015	(r292569)
+++ head/etc/mtree/BSD.tests.dist	Mon Dec 21 21:24:03 2015	(r292570)
@@ -386,6 +386,12 @@
         ..
         kqueue
         ..
+        mac
+            bsdextended
+            ..
+            portacl
+            ..
+        ..
         mqueue
         ..
         netinet

Modified: head/tests/sys/Makefile
==============================================================================
--- head/tests/sys/Makefile	Mon Dec 21 21:15:23 2015	(r292569)
+++ head/tests/sys/Makefile	Mon Dec 21 21:24:03 2015	(r292570)
@@ -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

Added: head/tests/sys/mac/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/Makefile	Mon Dec 21 21:24:03 2015	(r292570)
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+TESTSDIR=	${TESTSBASE}/sys/mac
+
+TESTS_SUBDIRS+=	bsdextended
+TESTS_SUBDIRS+=	portacl
+
+.include <bsd.test.mk>

Added: head/tests/sys/mac/bsdextended/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/bsdextended/Makefile	Mon Dec 21 21:24:03 2015	(r292570)
@@ -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>

Copied: head/tests/sys/mac/bsdextended/matches_test.sh (from r292569, head/tools/regression/mac/mac_bsdextended/test_matches.sh)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/bsdextended/matches_test.sh	Mon Dec 21 21:24:03 2015	(r292570, copy of r292569, head/tools/regression/mac/mac_bsdextended/test_matches.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

Copied: head/tests/sys/mac/bsdextended/ugidfw_test.c (from r292569, head/tools/regression/mac/mac_bsdextended/test_ugidfw.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/bsdextended/ugidfw_test.c	Mon Dec 21 21:24:03 2015	(r292570, copy of r292569, head/tools/regression/mac/mac_bsdextended/test_ugidfw.c)
@@ -0,0 +1,257 @@
+/*-
+ * 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);
+	}
+
+	printf("1..%lu\n", nitems(test_users) + nitems(test_groups) +
+	    3 * nitems(test_strings) + 2);
+
+	/*
+	 * We can test some parts of the library without the MAC Framework
+	 * and policy loaded, so run those tests before calling
+	 * mac_is_present().
+	 */
+	test_libugidfw_strings();
+
+	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);
+	}
+
+	/*
+	 * 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);
+}

Copied: head/tests/sys/mac/portacl/LICENSE (from r292569, head/tools/regression/mac/mac_portacl/LICENSE)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/portacl/LICENSE	Mon Dec 21 21:24:03 2015	(r292570, copy of r292569, head/tools/regression/mac/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.

Added: head/tests/sys/mac/portacl/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/portacl/Makefile	Mon Dec 21 21:24:03 2015	(r292570)
@@ -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>

Copied: head/tests/sys/mac/portacl/misc.sh (from r292569, head/tools/regression/mac/mac_portacl/misc.sh)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/portacl/misc.sh	Mon Dec 21 21:24:03 2015	(r292570, copy of r292569, head/tools/regression/mac/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
+}

Copied: head/tests/sys/mac/portacl/nobody_test.sh (from r292569, head/tools/regression/mac/mac_portacl/nobody.t)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/portacl/nobody_test.sh	Mon Dec 21 21:24:03 2015	(r292570, copy of r292569, head/tools/regression/mac/mac_portacl/nobody.t)
@@ -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

Copied: head/tests/sys/mac/portacl/root_test.sh (from r292569, head/tools/regression/mac/mac_portacl/root.t)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tests/sys/mac/portacl/root_test.sh	Mon Dec 21 21:24:03 2015	(r292570, copy of r292569, head/tools/regression/mac/mac_portacl/root.t)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512212124.tBLLO3l8011715>