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.
This commit is contained in:
parent
579e9f977b
commit
ba47b21115
9
tools/regression/security/cap_test/Makefile
Normal file
9
tools/regression/security/cap_test/Makefile
Normal file
@ -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>
|
47
tools/regression/security/cap_test/cap_test.c
Normal file
47
tools/regression/security/cap_test/cap_test.c
Normal file
@ -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);
|
||||
}
|
38
tools/regression/security/cap_test/cap_test.h
Normal file
38
tools/regression/security/cap_test/cap_test.h
Normal file
@ -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 */
|
426
tools/regression/security/cap_test/cap_test_capmode.c
Normal file
426
tools/regression/security/cap_test/cap_test_capmode.c
Normal file
@ -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);
|
||||
}
|
67
tools/regression/security/cap_test/cap_test_sysctl.c
Normal file
67
tools/regression/security/cap_test/cap_test_sysctl.c
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user