mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
The following change imports google/capsicum-test@9333154 from GitHub, omitting the embedded version of googletest, as well as the incomplete libcasper. This test suite helps verify capsicum(3) support via functional tests written in the GoogleTest test framework. Kernel support for capsicum(4) is tested by side-effect of testing capsicum(3). NB: as discussed in a previous [closed] PR [1], the casper(3) tests are incomplete/buggy and will not pass on FreeBSD. Thus, I have no intention of integrating them into the build/test on FreeBSD as-is. The import command used was: ``` curl -L https://github.com/google/capsicum-test/tarball/9333154 | tar --strip-components=1 -xvzf - -C dist/ rm -Rf dist/*/ ``` 1. https://github.com/google/capsicum-test/pull/26 Reviewed by: emaste (mentor) Differential Revision: https://reviews.freebsd.org/D19261
100 lines
3.2 KiB
C++
100 lines
3.2 KiB
C++
// Tests for POSIX message queue functionality.
|
|
|
|
#include <time.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <mqueue.h>
|
|
|
|
#include <string>
|
|
|
|
#include "capsicum.h"
|
|
#include "syscalls.h"
|
|
#include "capsicum-test.h"
|
|
|
|
// Run a test case in a forked process, possibly cleaning up a
|
|
// message after completion
|
|
#define FORK_TEST_ON_MQ(test_case_name, test_name, test_mq) \
|
|
static void test_case_name##_##test_name##_ForkTest(); \
|
|
TEST(test_case_name, test_name ## Forked) { \
|
|
_RUN_FORKED_FN(test_case_name##_##test_name##_ForkTest, \
|
|
#test_case_name, #test_name); \
|
|
const char *mqname = test_mq; \
|
|
if (mqname) mq_unlink_(mqname); \
|
|
} \
|
|
static void test_case_name##_##test_name##_ForkTest()
|
|
|
|
static bool invoked;
|
|
void seen_it_done_it(int v) {
|
|
invoked = true;
|
|
}
|
|
|
|
FORK_TEST_ON_MQ(PosixMqueue, CapMode, "/cap_mq") {
|
|
int mq = mq_open_("/cap_mq", O_RDWR|O_CREAT, 0644, NULL);
|
|
// On FreeBSD, turn on message queue support with:
|
|
// - 'kldload mqueuefs'
|
|
// - 'options P1003_1B_MQUEUE' in kernel build config.
|
|
if (mq < 0 && errno == ENOSYS) {
|
|
TEST_SKIPPED("mq_open -> -ENOSYS");
|
|
return;
|
|
}
|
|
EXPECT_OK(mq);
|
|
cap_rights_t r_read;
|
|
cap_rights_init(&r_read, CAP_READ);
|
|
cap_rights_t r_write;
|
|
cap_rights_init(&r_write, CAP_WRITE);
|
|
cap_rights_t r_poll;
|
|
cap_rights_init(&r_poll, CAP_EVENT);
|
|
|
|
int cap_read_mq = dup(mq);
|
|
EXPECT_OK(cap_read_mq);
|
|
EXPECT_OK(cap_rights_limit(cap_read_mq, &r_read));
|
|
int cap_write_mq = dup(mq);
|
|
EXPECT_OK(cap_write_mq);
|
|
EXPECT_OK(cap_rights_limit(cap_write_mq, &r_write));
|
|
int cap_poll_mq = dup(mq);
|
|
EXPECT_OK(cap_poll_mq);
|
|
EXPECT_OK(cap_rights_limit(cap_poll_mq, &r_poll));
|
|
EXPECT_OK(mq_close_(mq));
|
|
|
|
signal(SIGUSR2, seen_it_done_it);
|
|
|
|
EXPECT_OK(cap_enter()); // Enter capability mode
|
|
|
|
// Can no longer access the message queue via the POSIX IPC namespace.
|
|
EXPECT_CAPMODE(mq_open_("/cap_mw", O_RDWR|O_CREAT, 0644, NULL));
|
|
|
|
struct sigevent se;
|
|
se.sigev_notify = SIGEV_SIGNAL;
|
|
se.sigev_signo = SIGUSR2;
|
|
EXPECT_OK(mq_notify_(cap_poll_mq, &se));
|
|
EXPECT_NOTCAPABLE(mq_notify_(cap_read_mq, &se));
|
|
EXPECT_NOTCAPABLE(mq_notify_(cap_write_mq, &se));
|
|
|
|
const unsigned int kPriority = 10;
|
|
const char* message = "xyzzy";
|
|
struct timespec ts;
|
|
ts.tv_sec = 1;
|
|
ts.tv_nsec = 0;
|
|
EXPECT_OK(mq_timedsend_(cap_write_mq, message, strlen(message) + 1, kPriority, &ts));
|
|
EXPECT_NOTCAPABLE(mq_timedsend_(cap_read_mq, message, strlen(message) + 1, kPriority, &ts));
|
|
|
|
sleep(1); // Give the notification a chance to arrive.
|
|
EXPECT_TRUE(invoked);
|
|
|
|
struct mq_attr mqa;
|
|
EXPECT_OK(mq_getattr_(cap_poll_mq, &mqa));
|
|
EXPECT_OK(mq_setattr_(cap_poll_mq, &mqa, NULL));
|
|
EXPECT_NOTCAPABLE(mq_getattr_(cap_write_mq, &mqa));
|
|
|
|
char* buffer = (char *)malloc(mqa.mq_msgsize);
|
|
unsigned int priority;
|
|
EXPECT_NOTCAPABLE(mq_timedreceive_(cap_write_mq, buffer, mqa.mq_msgsize, &priority, &ts));
|
|
EXPECT_OK(mq_timedreceive_(cap_read_mq, buffer, mqa.mq_msgsize, &priority, &ts));
|
|
EXPECT_EQ(std::string(message), std::string(buffer));
|
|
EXPECT_EQ(kPriority, priority);
|
|
free(buffer);
|
|
|
|
close(cap_read_mq);
|
|
close(cap_write_mq);
|
|
close(cap_poll_mq);
|
|
}
|