Page MenuHomeFreeBSD

D28451.id83244.diff
No OneTemporary

D28451.id83244.diff

Index: tests/sys/audit/Makefile
===================================================================
--- tests/sys/audit/Makefile
+++ tests/sys/audit/Makefile
@@ -52,6 +52,9 @@
TEST_METADATA+= required_files="/etc/rc.d/auditd /dev/auditpipe"
LDFLAGS+= -lbsm -lutil
+OPENBSMDIR=${SRCTOP}/contrib/openbsm
+CFLAGS+= -I${OPENBSMDIR}
+LDADD+= ${LIBAUDITD}
CFLAGS.process-control.c+= -I${SRCTOP}/tests
Index: tests/sys/audit/administrative.c
===================================================================
--- tests/sys/audit/administrative.c
+++ tests/sys/audit/administrative.c
@@ -341,10 +341,16 @@
* at the configured path. To reset this, we need to stop and start the
* auditd(8) again. Here, we check if auditd(8) was running already
* before the test started. If so, we stop and start it again.
+ *
+ * TODO: should we skip this test if auditd(8) is already running to
+ * avoid restarting it?
*/
- system("service auditd onestop > /dev/null 2>&1");
- if (!atf_utils_file_exists("started_auditd"))
+ if (!atf_utils_file_exists("started_fake_auditd")) {
+ system("service auditd onestop > /dev/null 2>&1");
system("service auditd onestart > /dev/null 2>&1");
+ } else {
+ cleanup();
+ }
}
Index: tests/sys/audit/utils.c
===================================================================
--- tests/sys/audit/utils.c
+++ tests/sys/audit/utils.c
@@ -30,6 +30,7 @@
#include <sys/ioctl.h>
#include <bsm/libbsm.h>
+#include <bsm/auditd_lib.h>
#include <security/audit/audit_ioctl.h>
#include <atf-c.h>
@@ -222,13 +223,44 @@
}
}
-FILE
-*setup(struct pollfd fd[], const char *name)
+static bool
+is_auditd_running(void)
+{
+ int trigger;
+ int err;
+
+ /*
+ * AUDIT_TRIGGER_INITIALIZE is a no-op message on FreeBSD and can
+ * therefore be used to check whether auditd has already been started.
+ * This is significantly cheaper than running `service auditd onestatus`
+ * for each test case. It is also slightly less racy since it will only
+ * return true once auditd() has opened the trigger file rather than
+ * just when the pidfile has been created.
+ */
+ trigger = AUDIT_TRIGGER_INITIALIZE;
+ err = auditon(A_SENDTRIGGER, &trigger, sizeof(trigger));
+ if (err == 0) {
+ fprintf(stderr, "auditd(8) is running.\n");
+ return (true);
+ } else {
+ /*
+ * A_SENDTRIGGER returns ENODEV if auditd isn't listening,
+ * all other error codes indicate a fatal error.
+ */
+ ATF_REQUIRE_MSG(errno == ENODEV,
+ "Unexpected error from auditon(2): %s", strerror(errno));
+ return (false);
+ }
+
+}
+
+FILE *
+setup(struct pollfd fd[], const char *name)
{
au_mask_t fmask, nomask;
+ FILE *pipestream;
fmask = get_audit_mask(name);
nomask = get_audit_mask("no");
- FILE *pipestream;
ATF_REQUIRE((fd[0].fd = open("/dev/auditpipe", O_RDONLY)) != -1);
ATF_REQUIRE((pipestream = fdopen(fd[0].fd, "r")) != NULL);
@@ -244,12 +276,32 @@
/* Set local preselection audit_class as "no" for audit startup */
set_preselect_mode(fd[0].fd, &nomask);
- ATF_REQUIRE_EQ(0, system("service auditd onestatus || \
- { service auditd onestart && touch started_auditd ; }"));
-
- /* If 'started_auditd' exists, that means we started auditd(8) */
- if (atf_utils_file_exists("started_auditd"))
+ if (!is_auditd_running()) {
+ fprintf(stderr, "Starting fake auditd(8) for testing... ");
+ /*
+ * Previously, this test started auditd using
+ * `service auditd onestart`. However, there is a race condition
+ * there since service can return before auditd(8) has
+ * fully started (once the daemon parent process has forked)
+ * and this can cause check_audit_startup() to fail sometimes.
+ *
+ * In the CheriBSD CI this caused the first test executed by
+ * kyua (administrative:acct_failure) to fail every time, but
+ * subsequent ones would almost always succeed.
+ *
+ * To avoid this problem (and as a nice side-effect this speeds
+ * up the test quite a bit), we register this process as a
+ * "fake" auditd(8) using the audit_quick_start() function from
+ * libauditd.
+ */
+ atf_utils_create_file("started_fake_auditd", "yes\n");
+ ATF_REQUIRE(atf_utils_file_exists("started_fake_auditd"));
+ ATF_REQUIRE_EQ_MSG(0, audit_quick_start(),
+ "Failed to start fake auditd: %m");
+ fprintf(stderr, "done.\n");
+ /* audit_quick_start() should log an audit start event. */
check_audit_startup(fd, "audit startup", pipestream);
+ }
/* Set local preselection parameters specific to "name" audit_class */
set_preselect_mode(fd[0].fd, &fmask);
@@ -259,6 +311,12 @@
void
cleanup(void)
{
- if (atf_utils_file_exists("started_auditd"))
- system("service auditd onestop > /dev/null 2>&1");
+ if (atf_utils_file_exists("started_fake_auditd")) {
+ fprintf(stderr, "Stopping fake auditd(8)... ");
+ if (audit_quick_stop() != 0) {
+ fprintf(stderr, "Failed to stop fake auditd: %m\n");
+ abort();
+ }
+ fprintf(stderr, "done.\n");
+ }
}

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 6, 1:17 AM (11 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16484248
Default Alt Text
D28451.id83244.diff (4 KB)

Event Timeline