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);
+}
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to