Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/audit/process-control.c
Show All 20 Lines | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/capsicum.h> | |||||
#include <sys/ioctl.h> | |||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/ktrace.h> | #include <sys/ktrace.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/procctl.h> | #include <sys/procctl.h> | ||||
#include <sys/ptrace.h> | #include <sys/ptrace.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <sys/rtprio.h> | #include <sys/rtprio.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/sysctl.h> | |||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <bsm/audit.h> | |||||
#include <security/audit/audit_ioctl.h> | |||||
#include <atf-c.h> | #include <atf-c.h> | ||||
#include <errno.h> | |||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "utils.h" | #include "utils.h" | ||||
Show All 31 Lines | |||||
} | } | ||||
/* | /* | ||||
* No fork(2) in failure mode since possibilities for failure are only when | * No fork(2) in failure mode since possibilities for failure are only when | ||||
* user is not privileged or when the number of processes exceed KERN_MAXPROC. | * user is not privileged or when the number of processes exceed KERN_MAXPROC. | ||||
*/ | */ | ||||
ATF_TC_WITH_CLEANUP(_exit_success); | |||||
ATF_TC_HEAD(_exit_success, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " | |||||
"_exit(2) call"); | |||||
} | |||||
ATF_TC_BODY(_exit_success, tc) | |||||
{ | |||||
FILE *pipefd = setup(fds, auclass); | |||||
/* | |||||
* Disable stream buffering for read operations from /dev/auditpipe. | |||||
* Since for _exit(2), obtained audit record is not enough to fill up | |||||
* fread(3)'s buffer called through au_read_rec(3). | |||||
*/ | |||||
ATF_REQUIRE_EQ(0, setvbuf(pipefd, NULL, _IONBF, 0)); | |||||
ATF_REQUIRE((pid = fork()) != -1); | |||||
if (pid) { | |||||
snprintf(pcregex, sizeof(pcregex), "exit.*%d.*success", pid); | |||||
check_audit(fds, pcregex, pipefd); | |||||
} | |||||
else | |||||
_exit(0); | |||||
} | |||||
ATF_TC_CLEANUP(_exit_success, tc) | |||||
{ | |||||
cleanup(); | |||||
} | |||||
/* | |||||
* _exit(2) never returns, hence the auditing by default is always successful | |||||
*/ | |||||
ATF_TC_WITH_CLEANUP(rfork_success); | ATF_TC_WITH_CLEANUP(rfork_success); | ||||
ATF_TC_HEAD(rfork_success, tc) | ATF_TC_HEAD(rfork_success, tc) | ||||
{ | { | ||||
atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " | atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " | ||||
"rfork(2) call"); | "rfork(2) call"); | ||||
} | } | ||||
ATF_TC_BODY(rfork_success, tc) | ATF_TC_BODY(rfork_success, tc) | ||||
▲ Show 20 Lines • Show All 1,371 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
ATF_TC_CLEANUP(procctl_failure, tc) | ATF_TC_CLEANUP(procctl_failure, tc) | ||||
{ | { | ||||
cleanup(); | cleanup(); | ||||
} | } | ||||
ATF_TC_WITH_CLEANUP(cap_enter_success); | |||||
ATF_TC_HEAD(cap_enter_success, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " | |||||
"cap_enter(2) call"); | |||||
} | |||||
ATF_TC_BODY(cap_enter_success, tc) | |||||
{ | |||||
int capinfo; | |||||
size_t len = sizeof(capinfo); | |||||
const char *capname = "kern.features.security_capability_mode"; | |||||
ATF_REQUIRE_EQ(0, sysctlbyname(capname, &capinfo, &len, NULL, 0)); | |||||
/* Without CAPABILITY_MODE enabled, cap_enter() returns ENOSYS */ | |||||
if (!capinfo) | |||||
atf_tc_skip("Capsicum is not enabled in the system"); | |||||
FILE *pipefd = setup(fds, auclass); | |||||
/* | |||||
* Disable stream buffering for read operations from /dev/auditpipe. | |||||
* Since for cap_enter(2), obtained audit record is not enough to fill | |||||
* up fread(3)'s buffer called through au_read_rec(3). | |||||
*/ | |||||
ATF_REQUIRE_EQ(0, setvbuf(pipefd, NULL, _IONBF, 0)); | |||||
ATF_REQUIRE((pid = fork()) != -1); | |||||
if (pid) { | |||||
snprintf(pcregex, sizeof(pcregex), | |||||
"cap_enter.*%d.*return,success", pid); | |||||
ATF_REQUIRE(wait(&status) != -1); | |||||
check_audit(fds, pcregex, pipefd); | |||||
} | |||||
else { | |||||
ATF_REQUIRE_EQ(0, cap_enter()); | |||||
_exit(0); | |||||
} | |||||
} | |||||
ATF_TC_CLEANUP(cap_enter_success, tc) | |||||
{ | |||||
cleanup(); | |||||
} | |||||
ATF_TC_WITH_CLEANUP(cap_getmode_success); | |||||
ATF_TC_HEAD(cap_getmode_success, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " | |||||
"cap_getmode(2) call"); | |||||
} | |||||
ATF_TC_BODY(cap_getmode_success, tc) | |||||
{ | |||||
int capinfo, modep; | |||||
size_t len = sizeof(capinfo); | |||||
const char *capname = "kern.features.security_capability_mode"; | |||||
ATF_REQUIRE_EQ(0, sysctlbyname(capname, &capinfo, &len, NULL, 0)); | |||||
/* Without CAPABILITY_MODE enabled, cap_getmode() returns ENOSYS */ | |||||
if (!capinfo) | |||||
atf_tc_skip("Capsicum is not enabled in the system"); | |||||
pid = getpid(); | |||||
snprintf(pcregex, sizeof(pcregex), "cap_getmode.*%d.*success", pid); | |||||
FILE *pipefd = setup(fds, auclass); | |||||
ATF_REQUIRE_EQ(0, cap_getmode(&modep)); | |||||
check_audit(fds, pcregex, pipefd); | |||||
} | |||||
ATF_TC_CLEANUP(cap_getmode_success, tc) | |||||
{ | |||||
cleanup(); | |||||
} | |||||
ATF_TC_WITH_CLEANUP(cap_getmode_failure); | |||||
ATF_TC_HEAD(cap_getmode_failure, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " | |||||
"cap_getmode(2) call"); | |||||
} | |||||
ATF_TC_BODY(cap_getmode_failure, tc) | |||||
{ | |||||
pid = getpid(); | |||||
snprintf(pcregex, sizeof(pcregex), "cap_getmode.*%d.*failure", pid); | |||||
FILE *pipefd = setup(fds, auclass); | |||||
/* cap_getmode(2) can either fail with EFAULT or ENOSYS */ | |||||
ATF_REQUIRE_EQ(-1, cap_getmode(NULL)); | |||||
check_audit(fds, pcregex, pipefd); | |||||
} | |||||
ATF_TC_CLEANUP(cap_getmode_failure, tc) | |||||
{ | |||||
cleanup(); | |||||
} | |||||
ATF_TP_ADD_TCS(tp) | ATF_TP_ADD_TCS(tp) | ||||
{ | { | ||||
ATF_TP_ADD_TC(tp, fork_success); | ATF_TP_ADD_TC(tp, fork_success); | ||||
ATF_TP_ADD_TC(tp, _exit_success); | |||||
ATF_TP_ADD_TC(tp, rfork_success); | ATF_TP_ADD_TC(tp, rfork_success); | ||||
ATF_TP_ADD_TC(tp, rfork_failure); | ATF_TP_ADD_TC(tp, rfork_failure); | ||||
ATF_TP_ADD_TC(tp, wait4_success); | ATF_TP_ADD_TC(tp, wait4_success); | ||||
ATF_TP_ADD_TC(tp, wait4_failure); | ATF_TP_ADD_TC(tp, wait4_failure); | ||||
ATF_TP_ADD_TC(tp, wait6_success); | ATF_TP_ADD_TC(tp, wait6_success); | ||||
ATF_TP_ADD_TC(tp, wait6_failure); | ATF_TP_ADD_TC(tp, wait6_failure); | ||||
ATF_TP_ADD_TC(tp, kill_success); | ATF_TP_ADD_TC(tp, kill_success); | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | ATF_TP_ADD_TCS(tp) | ||||
ATF_TP_ADD_TC(tp, profil_success); | ATF_TP_ADD_TC(tp, profil_success); | ||||
ATF_TP_ADD_TC(tp, profil_failure); | ATF_TP_ADD_TC(tp, profil_failure); | ||||
ATF_TP_ADD_TC(tp, ptrace_success); | ATF_TP_ADD_TC(tp, ptrace_success); | ||||
ATF_TP_ADD_TC(tp, ptrace_failure); | ATF_TP_ADD_TC(tp, ptrace_failure); | ||||
ATF_TP_ADD_TC(tp, ktrace_success); | ATF_TP_ADD_TC(tp, ktrace_success); | ||||
ATF_TP_ADD_TC(tp, ktrace_failure); | ATF_TP_ADD_TC(tp, ktrace_failure); | ||||
ATF_TP_ADD_TC(tp, procctl_success); | ATF_TP_ADD_TC(tp, procctl_success); | ||||
ATF_TP_ADD_TC(tp, procctl_failure); | ATF_TP_ADD_TC(tp, procctl_failure); | ||||
ATF_TP_ADD_TC(tp, cap_enter_success); | |||||
ATF_TP_ADD_TC(tp, cap_getmode_success); | |||||
ATF_TP_ADD_TC(tp, cap_getmode_failure); | |||||
return (atf_no_error()); | return (atf_no_error()); | ||||
} | } |