Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 May 2011 12:44:46 +0000 (UTC)
From:      Jonathan Anderson <jonathan@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r221431 - head/tools/regression/security/cap_test
Message-ID:  <201105041244.p44CikvT049911@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jonathan
Date: Wed May  4 12:44:46 2011
New Revision: 221431
URL: http://svn.freebsd.org/changeset/base/221431

Log:
  Regression tests for Capsicum capability mode.
  
  Ensure that system calls that access global namespaces, e.g. open(2), are not permitted, and that whitelisted sysctls like kern.osreldate are.
  
  Approved by: rwatson
  Sponsored by: Google, Inc.

Added:
  head/tools/regression/security/cap_test/
  head/tools/regression/security/cap_test/Makefile   (contents, props changed)
  head/tools/regression/security/cap_test/cap_test.c   (contents, props changed)
  head/tools/regression/security/cap_test/cap_test.h   (contents, props changed)
  head/tools/regression/security/cap_test/cap_test_capmode.c   (contents, props changed)
  head/tools/regression/security/cap_test/cap_test_sysctl.c   (contents, props changed)

Added: head/tools/regression/security/cap_test/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/security/cap_test/Makefile	Wed May  4 12:44:46 2011	(r221431)
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG=	cap_test
+SRCS=	cap_test.c cap_test_capmode.c cap_test_sysctl.c
+WARNS=	3
+NO_MAN=
+CFLAGS+=	-DMACHINE=\"${MACHINE}\"
+
+.include <bsd.prog.mk>

Added: head/tools/regression/security/cap_test/cap_test.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/security/cap_test/cap_test.c	Wed May  4 12:44:46 2011	(r221431)
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2008-2011 Robert N. M. Watson
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+
+#include "cap_test.h"
+
+int
+main(int argc, char *argv[])
+{
+	test_capmode();
+	test_sysctl();
+	/*
+	test_capabilities();
+	test_syscalls();
+	test_fcntl();
+	*/
+	exit(0);
+}

Added: head/tools/regression/security/cap_test/cap_test.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/security/cap_test/cap_test.h	Wed May  4 12:44:46 2011	(r221431)
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2008-2011 Robert N. M. Watson
+ * 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$
+ */
+
+#ifndef CAP_TEST_H
+#define	CAP_TEST_H
+
+void	test_capmode(void);
+void	test_capabilities(void);
+void	test_syscalls(void);
+void	test_sysctl(void);
+void	test_fcntl(void);
+
+#endif /* CAP_TEST_H */

Added: head/tools/regression/security/cap_test/cap_test_capmode.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/security/cap_test/cap_test_capmode.c	Wed May  4 12:44:46 2011	(r221431)
@@ -0,0 +1,426 @@
+/*-
+ * Copyright (c) 2008-2009 Robert N. M. Watson
+ * 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$
+ */
+
+/*
+ * Test routines to make sure a variety of system calls are or are not
+ * available in capability mode.  The goal is not to see if they work, just
+ * whether or not they return the expected ECAPMODE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/capability.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <machine/sysarch.h>
+#include <netinet/in.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Need to check machine-dependent sysarch(). */
+#define	ARCH_IS(s)	(!strncmp(s, MACHINE, sizeof(s) + 1))
+
+#include "cap_test.h"
+
+void
+test_capmode(void)
+{
+	struct sockaddr_in sin;
+	struct statfs statfs;
+	struct stat sb;
+	ssize_t len;
+	long sysarch_arg = 0;
+	int fd, fd_close, fd_dir, fd_file, fd_socket, fd2[2], ret;
+	pid_t pid, wpid;
+	char ch;
+
+	fd_file = open("/tmp/cap_test_syscalls", O_RDWR|O_CREAT, 0644);
+	if (fd_file < 0)
+		err(-1, "test_syscalls:prep: open cap_test_syscalls");
+
+	fd_close = open("/dev/null", O_RDWR);
+	if (fd_close < 0)
+		err(-1, "test_syscalls:prep: open /dev/null");
+
+	fd_dir = open("/tmp", O_RDONLY);
+	if (fd_dir < 0)
+		err(-1, "test_syscalls:prep: open /tmp");
+
+	fd_socket = socket(PF_INET, SOCK_DGRAM, 0);
+	if (fd_socket < 0)
+		err(-1, "test_syscalls:prep: socket");
+
+	if (cap_enter() < 0)
+		err(-1, "test_syscalls:prep: cap_enter");
+
+
+	bzero(&sin, sizeof(sin));
+	sin.sin_len = sizeof(sin);
+	sin.sin_family = AF_INET;
+
+	/*
+	 * Here begin the tests, sorted roughly alphabetically by system call
+	 * name.
+	 */
+	fd = accept(fd_socket, NULL, NULL);
+	if (fd < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:accept");
+	} else {
+		warnx("test_syscalls:accept succeeded");
+		close(fd);
+	}
+
+	if (access("/tmp/cap_test_syscalls_access", F_OK) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:access");
+	} else
+		warnx("test_syscalls:access succeeded");
+
+	if (acct("/tmp/cap_test_syscalls_acct") < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:acct");
+	} else
+		warnx("test_syscalls:acct succeeded");
+
+	if (bind(PF_INET, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscall:bind");
+	} else
+		warnx("test_syscall:bind succeeded");
+
+	if (chdir("/tmp/cap_test_syscalls_chdir") < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:chdir");
+	} else
+		warnx("test_syscalls:chdir succeeded");
+
+	if (chflags("/tmp/cap_test_syscalls_chflags", UF_NODUMP) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:chflags");
+	} else
+		warnx("test_syscalls:chflags succeeded");
+
+	if (chmod("/tmp/cap_test_syscalls_chmod", 0644) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:chmod");
+	} else
+		warnx("test_syscalls:chmod succeeded");
+
+	if (chown("/tmp/cap_test_syscalls_chown", -1, -1) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:chown");
+	} else
+		warnx("test_syscalls:chown succeeded");
+
+	if (chroot("/tmp/cap_test_syscalls_chroot") < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:chroot");
+	} else
+		warnx("test_syscalls:chroot succeeded");
+
+	if (close(fd_close)) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:close");
+		else
+			warn("test_syscalls:close");
+	}
+
+	if (connect(PF_INET, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscall:connect");
+	} else
+		warnx("test_syscall:connect succeeded");
+
+	fd = creat("/tmp/cap_test_syscalls_creat", 0644);
+	if (fd >= 0) {
+		warnx("test_syscalls:creat succeeded");
+		close(fd);
+	} else if (errno != ECAPMODE)
+		warn("test_syscalls:creat");
+
+	fd = dup(fd_file);
+	if (fd < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:dup");
+	} else
+		close(fd);
+
+	if (fchdir(fd_dir) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscall:fchdir");
+	} else
+		warnx("test_syscalls:fchdir succeeded");
+
+	if (fchflags(fd_file, UF_NODUMP) < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscall:fchflags");
+	}
+
+	pid = fork();
+	if (pid >= 0) {
+		if (pid == 0) {
+			exit(0);
+		} else if (pid > 0) {
+			wpid = waitpid(pid, NULL, 0);
+			if (wpid < 0) {
+				if (errno != ECAPMODE)
+					warn("test_syscalls:waitpid");
+			} else
+				warnx("test_syscalls:waitpid succeeded");
+		}
+	} else
+		warn("test_syscalls:fork");
+
+	if (fstat(fd_file, &sb) < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:fstat");
+	}
+
+	/*
+	 * getegid() can't return an error but check for it anyway.
+	 */
+	errno = 0;
+	(void)getegid();
+	if (errno == ECAPMODE)
+		warnx("test_syscalls:getegid");
+
+	/*
+	 * geteuid() can't return an error but check for it anyway.
+	 */
+	errno = 0;
+	geteuid();
+	if (errno == ECAPMODE)
+		warnx("test_syscalls:geteuid");
+
+	if (getfsstat(&statfs, sizeof(statfs), MNT_NOWAIT) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:getfsstat");
+	} else
+		warnx("test_syscalls:getfsstat succeeded");
+
+	/*
+	 * getgid() can't return an error but check for it anyway.
+	 */
+	errno = 0;
+	getgid();
+	if (errno == ECAPMODE)
+		warnx("test_syscalls:getgid");
+
+	if (getpeername(fd_socket, NULL, NULL) < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:getpeername");
+	}
+
+	if (getlogin() == NULL)
+		warn("test_sycalls:getlogin %d", errno);
+
+	/*
+	 * getpid() can't return an error but check for it anyway.
+	 */
+	errno = 0;
+	(void)getpid();
+	if (errno == ECAPMODE)
+		warnx("test_syscalls:getpid");
+
+	/*
+	 * getppid() can't return an error but check for it anyway.
+	 */
+	errno = 0;
+	(void)getppid();
+	if (errno == ECAPMODE)
+		warnx("test_syscalls:getppid");
+
+	if (getsockname(fd_socket, NULL, NULL) < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:getsockname");
+	}
+
+	/*
+	 * getuid() can't return an error but check for it anyway.
+	 */
+	errno = 0;
+	(void)getuid();
+	if (errno == ECAPMODE)
+		warnx("test_syscalls:getuid");
+
+	/* XXXRW: ktrace */
+
+	if (link("/tmp/foo", "/tmp/bar") < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:link");
+	} else
+		warnx("test_syscalls:link succeeded");
+
+	ret = lseek(fd_file, SEEK_SET, 0);
+	if (ret < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:lseek");
+		else
+			warn("test_syscalls:lseek");
+	}
+
+	if (lstat("/tmp/cap_test_syscalls_lstat", &sb) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:lstat");
+	} else
+		warnx("test_syscalls:lstat succeeded");
+
+	if (mknod("/tmp/test_syscalls_mknod", 06440, 0) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:mknod");
+	} else
+		warnx("test_syscalls:mknod succeeded");
+
+	/*
+	 * mount() is a bit tricky but do our best.
+	 */
+	if (mount("procfs", "/not_mounted", 0, NULL) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:mount");
+	} else
+		warnx("test_syscalls:mount succeeded");
+
+	if (msync(&fd_file, 8192, MS_ASYNC) < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:msync");
+	}
+
+	fd = open("/dev/null", O_RDWR);
+	if (fd >= 0) {
+		warnx("test_syscalls:open succeeded");
+		close(fd);
+	}
+
+	if (pipe(fd2) == 0) {
+		close(fd2[0]);
+		close(fd2[1]);
+	} else if (errno == ECAPMODE)
+		warnx("test_syscalls:pipe");
+
+	if (profil(NULL, 0, 0, 0) < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:profile");
+	}
+
+	/* XXXRW: ptrace. */
+
+	len = read(fd_file, &ch, sizeof(ch));
+	if (len < 0 && errno == ECAPMODE)
+		warnx("test_syscalls:read");
+
+	if (readlink("/tmp/cap_test_syscalls_readlink", NULL, 0) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:readlink");
+	} else
+		warnx("test_syscalls:readlink succeeded");
+
+	len = recvfrom(fd_socket, NULL, 0, 0, NULL, NULL);
+	if (len < 0 && errno == ECAPMODE)
+		warnx("test_syscalls:recvfrom");
+
+	len = recvmsg(fd_socket, NULL, 0);
+	if (len < 0 && errno == ECAPMODE)
+		warnx("test_syscalls:recvmsg");
+
+	if (revoke("/tmp/cap_test_syscalls_revoke") < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:revoke");
+	} else
+		warnx("test_syscalls:revoke succeeded");
+
+	len = sendmsg(fd_socket, NULL, 0);
+	if (len < 0 && errno == ECAPMODE)
+		warnx("test_syscalls:sendmsg");
+
+	len = sendto(fd_socket, NULL, 0, 0, NULL, 0);
+	if (len < 0 && errno == ECAPMODE)
+		warn("test_syscalls:sendto(NULL)");
+
+	if (setuid(getuid()) < 0) {
+		if (errno == ECAPMODE)
+			warnx("test_syscalls:setuid");
+	}
+
+	if (stat("/tmp/cap_test_syscalls_stat", &sb) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:stat");
+	} else
+		warnx("test_syscalls:stat succeeded");
+
+	if (symlink("/tmp/cap_test_syscalls_symlink_from",
+	    "/tmp/cap_test_syscalls_symlink_to") < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:symlink");
+	} else
+		warnx("test_syscalls:symlink succeeded");
+
+	/* sysarch() is, by definition, architecture-dependent */
+	if (ARCH_IS("i386") || ARCH_IS("amd64")) {
+		if (sysarch(I386_SET_IOPERM, &sysarch_arg) != -1)
+			warnx("test_syscalls:sysarch succeeded");
+		else if (errno != ECAPMODE)
+			warn("test_syscalls:sysarch errno != ECAPMODE");
+
+		/* XXXJA: write a test for arm */
+	} else {
+		warnx("test_syscalls:no sysarch() test for architecture '%s'", MACHINE);
+	}
+
+	/* XXXRW: No error return from sync(2) to test. */
+
+	if (unlink("/tmp/cap_test_syscalls_unlink") < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:unlink");
+	} else
+		warnx("test_syscalls:unlink succeeded");
+
+	if (unmount("/not_mounted", 0) < 0) {
+		if (errno != ECAPMODE)
+			warn("test_syscalls:unmount");
+	} else
+		warnx("test_syscalls:unmount succeeded");
+
+	len = write(fd_file, &ch, sizeof(ch));
+	if (len < 0 && errno == ECAPMODE)
+		warnx("test_syscalls:write");
+
+	exit(0);
+}

Added: head/tools/regression/security/cap_test/cap_test_sysctl.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/security/cap_test/cap_test_sysctl.c	Wed May  4 12:44:46 2011	(r221431)
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2008-2011 Robert N. M. Watson
+ * 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$
+ */
+
+/*
+ * Test that various sysctls are (and aren't) available on capability mode.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/capability.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "cap_test.h"
+
+/*
+ * Certain sysctls are permitted in capability mode, but most are not.  Test
+ * for the ones that should be, and try one or two that shouldn't.
+ */
+void
+test_sysctl(void)
+{
+	int error, i, oid[2];
+	size_t len;
+
+	oid[0] = CTL_KERN;
+	oid[1] = KERN_OSRELDATE;
+	len = sizeof(i);
+	error = sysctl(oid, 2, &i, &len, NULL, 0);
+	if (error)
+		warnx("capmode and kern.osreldate failed error %d", errno);
+
+	exit(0);
+}



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