Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Unified Diff: sandbox/linux/seccomp_bpf/demo.cc

Issue 10458040: Initial snapshot of the new BPF-enabled seccomp sandbox. This code is (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sandbox/linux/seccomp_bpf/demo.cc
===================================================================
--- sandbox/linux/seccomp_bpf/demo.cc (revision 0)
+++ sandbox/linux/seccomp_bpf/demo.cc (revision 0)
@@ -0,0 +1,175 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/unistd.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/ipc.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
+#include <sys/shm.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "sandbox.h"
+#include "util.h"
+
+#define ERR EPERM
+
+
+static void *threadFnc(void *arg) {
+ return arg;
+}
+
+static void *sendmsgStressThreadFnc(void *arg) {
+ static const int repetitions = 100;
+ static const int numFds = 3;
+ for (int rep = 0; rep < repetitions; ++rep) {
+ int fds[2 + numFds];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
+ perror("socketpair()");
+ _exit(1);
+ }
+ size_t len = 4;
+ char buf[4];
+ if (!playground2::Util::sendFds(fds[0], "test", 4,
+ fds[1], fds[1], fds[1], -1) ||
+ !playground2::Util::getFds(fds[1], buf, &len,
+ fds+2, fds+3, fds+4, NULL) ||
+ len != 4 ||
+ memcmp(buf, "test", len) ||
+ write(fds[2], "demo", 4) != 4 ||
+ read(fds[0], buf, 4) != 4 ||
+ memcmp(buf, "demo", 4)) {
+ perror("sending/receiving of fds");
+ _exit(1);
+ }
+ for (int i = 0; i < 2+numFds; ++i) {
+ if (close(fds[i])) {
+ perror("close");
+ _exit(1);
+ }
+ }
+ }
+ return NULL;
+}
+
+int main(int argc, char *argv[]) {
+ int proc_fd = open("/proc", O_RDONLY|O_DIRECTORY);
+ if (!SupportsSeccomp2Sandbox(proc_fd)) {
+ perror("sandbox");
+ _exit(1);
+ }
+ Seccomp2SandboxSetProcFd(proc_fd);
+ StartSeccomp2Sandbox();
+
+ // Check that we can create threads
+ pthread_t thr;
+ if (!pthread_create(&thr, NULL, threadFnc, (void *)0x1234)) {
+ void *ret;
+ pthread_join(thr, &ret);
+ if (ret != (void *)0x1234) {
+ perror("clone() failed");
+ _exit(1);
+ }
+ } else {
+ perror("clone() failed");
+ _exit(1);
+ }
+
+ // Check that we handle restart_syscall() without dieing. This is a little
+ // tricky to trigger. And I can't think of a good way to verify whether it
+ // actually executed.
+ signal(SIGALRM, SIG_IGN);
+ const struct itimerval tv = { { 0, 0 }, { 0, 5*1000 } };
+ const struct timespec tmo = { 0, 100*1000*1000 };
+ setitimer(ITIMER_REAL, &tv, NULL);
+ nanosleep(&tmo, NULL);
+
+ // Check that we can query the size of the stack, but that all other
+ // calls to getrlimit() fail.
+ if (((errno = 0), !getrlimit(RLIMIT_STACK, NULL)) || errno != EFAULT ||
+ ((errno = 0), !getrlimit(RLIMIT_CORE, NULL)) || errno != ERR) {
+ perror("getrlimit()");
+ _exit(1);
+ }
+
+ // Check that we can query TCGETS and TIOCGWINSZ, but no other ioctls().
+ if (((errno = 0), !ioctl(2, TCGETS, NULL)) || errno != EFAULT ||
+ ((errno = 0), !ioctl(2, TIOCGWINSZ, NULL)) || errno != EFAULT ||
+ ((errno = 0), !ioctl(2, TCSETS, NULL)) || errno != ERR) {
+ perror("ioctl()");
+ _exit(1);
+ }
+
+ // Check that prctl() can manipulate the dumpable flag, but nothing else.
+ if (((errno = 0), !prctl(PR_GET_DUMPABLE)) || errno ||
+ ((errno = 0), prctl(PR_SET_DUMPABLE, 1)) || errno ||
+ ((errno = 0), !prctl(PR_SET_SECCOMP, 0)) || errno != ERR) {
+ perror("prctl()");
+ _exit(1);
+ }
+
+ // Check that we can send and receive file handles.
+ int fds[3];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
+ perror("socketpair()");
+ _exit(1);
+ }
+ size_t len = 4;
+ char buf[4];
+ if (!playground2::Util::sendFds(fds[0], "test", 4, fds[1], -1) ||
+ !playground2::Util::getFds(fds[1], buf, &len, fds+2, NULL) ||
+ len != 4 ||
+ memcmp(buf, "test", len) ||
+ write(fds[2], "demo", 4) != 4 ||
+ read(fds[0], buf, 4) != 4 ||
+ memcmp(buf, "demo", 4) ||
+ close(fds[0]) ||
+ close(fds[1]) ||
+ close(fds[2])) {
+ perror("sending/receiving of fds");
+ _exit(1);
+ }
+
+ // Check whether SysV IPC works.
+ int shmid;
+ void *addr;
+ if ((shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT|0600)) < 0 ||
+ (addr = shmat(shmid, NULL, 0)) == (void *)-1 ||
+ shmdt(addr) ||
+ shmctl(shmid, IPC_RMID, NULL)) {
+ perror("sysv IPC");
+ _exit(1);
+ }
+
+ // Print a message so that the user can see the sandbox is activated.
+ time_t tm = time(NULL);
+ printf("Sandbox has been started at %s", ctime(&tm));
+
+ // Stress-test the sendmsg() code
+ static const int sendmsgStressNumThreads = 10;
+ pthread_t sendmsgStressThreads[sendmsgStressNumThreads];
+ for (int i = 0; i < sendmsgStressNumThreads; ++i) {
+ if (pthread_create(sendmsgStressThreads + i, NULL,
+ sendmsgStressThreadFnc, NULL)) {
+ perror("pthread_create");
+ _exit(1);
+ }
+ }
+ for (int i = 0; i < sendmsgStressNumThreads; ++i) {
+ pthread_join(sendmsgStressThreads[i], NULL);
+ }
+
+ return 0;
+}
Property changes on: sandbox/linux/seccomp_bpf/demo.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698