summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorjonathan <jonathan@FreeBSD.org>2011-05-04 12:44:46 +0000
committerjonathan <jonathan@FreeBSD.org>2011-05-04 12:44:46 +0000
commitba47b21115dfb5e5bdb6c1b75fe3ce743385aac4 (patch)
treead9b9f137bd64e558b8b13413c569ea7363da99e /tools
parent579e9f977b62dfe399809418ba51b99bb8710af5 (diff)
downloadFreeBSD-src-ba47b21115dfb5e5bdb6c1b75fe3ce743385aac4.zip
FreeBSD-src-ba47b21115dfb5e5bdb6c1b75fe3ce743385aac4.tar.gz
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.
Diffstat (limited to 'tools')
-rw-r--r--tools/regression/security/cap_test/Makefile9
-rw-r--r--tools/regression/security/cap_test/cap_test.c47
-rw-r--r--tools/regression/security/cap_test/cap_test.h38
-rw-r--r--tools/regression/security/cap_test/cap_test_capmode.c426
-rw-r--r--tools/regression/security/cap_test/cap_test_sysctl.c67
5 files changed, 587 insertions, 0 deletions
diff --git a/tools/regression/security/cap_test/Makefile b/tools/regression/security/cap_test/Makefile
new file mode 100644
index 0000000..86d495c
--- /dev/null
+++ b/tools/regression/security/cap_test/Makefile
@@ -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>
diff --git a/tools/regression/security/cap_test/cap_test.c b/tools/regression/security/cap_test/cap_test.c
new file mode 100644
index 0000000..5a2dc15
--- /dev/null
+++ b/tools/regression/security/cap_test/cap_test.c
@@ -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);
+}
diff --git a/tools/regression/security/cap_test/cap_test.h b/tools/regression/security/cap_test/cap_test.h
new file mode 100644
index 0000000..18fa814
--- /dev/null
+++ b/tools/regression/security/cap_test/cap_test.h
@@ -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 */
diff --git a/tools/regression/security/cap_test/cap_test_capmode.c b/tools/regression/security/cap_test/cap_test_capmode.c
new file mode 100644
index 0000000..9d20dec
--- /dev/null
+++ b/tools/regression/security/cap_test/cap_test_capmode.c
@@ -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);
+}
diff --git a/tools/regression/security/cap_test/cap_test_sysctl.c b/tools/regression/security/cap_test/cap_test_sysctl.c
new file mode 100644
index 0000000..4376eec
--- /dev/null
+++ b/tools/regression/security/cap_test/cap_test_sysctl.c
@@ -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);
+}
OpenPOWER on IntegriCloud