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

Side by Side 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, 6 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <linux/unistd.h>
4 #include <netinet/in.h>
5 #include <netinet/tcp.h>
6 #include <netinet/udp.h>
7 #include <pthread.h>
8 #include <signal.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/ioctl.h>
13 #include <sys/ipc.h>
14 #include <sys/mman.h>
15 #include <sys/prctl.h>
16 #include <sys/resource.h>
17 #include <sys/shm.h>
18 #include <sys/socket.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <time.h>
22 #include <unistd.h>
23
24 #include "sandbox.h"
25 #include "util.h"
26
27 #define ERR EPERM
28
29
30 static void *threadFnc(void *arg) {
31 return arg;
32 }
33
34 static void *sendmsgStressThreadFnc(void *arg) {
35 static const int repetitions = 100;
36 static const int numFds = 3;
37 for (int rep = 0; rep < repetitions; ++rep) {
38 int fds[2 + numFds];
39 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
40 perror("socketpair()");
41 _exit(1);
42 }
43 size_t len = 4;
44 char buf[4];
45 if (!playground2::Util::sendFds(fds[0], "test", 4,
46 fds[1], fds[1], fds[1], -1) ||
47 !playground2::Util::getFds(fds[1], buf, &len,
48 fds+2, fds+3, fds+4, NULL) ||
49 len != 4 ||
50 memcmp(buf, "test", len) ||
51 write(fds[2], "demo", 4) != 4 ||
52 read(fds[0], buf, 4) != 4 ||
53 memcmp(buf, "demo", 4)) {
54 perror("sending/receiving of fds");
55 _exit(1);
56 }
57 for (int i = 0; i < 2+numFds; ++i) {
58 if (close(fds[i])) {
59 perror("close");
60 _exit(1);
61 }
62 }
63 }
64 return NULL;
65 }
66
67 int main(int argc, char *argv[]) {
68 int proc_fd = open("/proc", O_RDONLY|O_DIRECTORY);
69 if (!SupportsSeccomp2Sandbox(proc_fd)) {
70 perror("sandbox");
71 _exit(1);
72 }
73 Seccomp2SandboxSetProcFd(proc_fd);
74 StartSeccomp2Sandbox();
75
76 // Check that we can create threads
77 pthread_t thr;
78 if (!pthread_create(&thr, NULL, threadFnc, (void *)0x1234)) {
79 void *ret;
80 pthread_join(thr, &ret);
81 if (ret != (void *)0x1234) {
82 perror("clone() failed");
83 _exit(1);
84 }
85 } else {
86 perror("clone() failed");
87 _exit(1);
88 }
89
90 // Check that we handle restart_syscall() without dieing. This is a little
91 // tricky to trigger. And I can't think of a good way to verify whether it
92 // actually executed.
93 signal(SIGALRM, SIG_IGN);
94 const struct itimerval tv = { { 0, 0 }, { 0, 5*1000 } };
95 const struct timespec tmo = { 0, 100*1000*1000 };
96 setitimer(ITIMER_REAL, &tv, NULL);
97 nanosleep(&tmo, NULL);
98
99 // Check that we can query the size of the stack, but that all other
100 // calls to getrlimit() fail.
101 if (((errno = 0), !getrlimit(RLIMIT_STACK, NULL)) || errno != EFAULT ||
102 ((errno = 0), !getrlimit(RLIMIT_CORE, NULL)) || errno != ERR) {
103 perror("getrlimit()");
104 _exit(1);
105 }
106
107 // Check that we can query TCGETS and TIOCGWINSZ, but no other ioctls().
108 if (((errno = 0), !ioctl(2, TCGETS, NULL)) || errno != EFAULT ||
109 ((errno = 0), !ioctl(2, TIOCGWINSZ, NULL)) || errno != EFAULT ||
110 ((errno = 0), !ioctl(2, TCSETS, NULL)) || errno != ERR) {
111 perror("ioctl()");
112 _exit(1);
113 }
114
115 // Check that prctl() can manipulate the dumpable flag, but nothing else.
116 if (((errno = 0), !prctl(PR_GET_DUMPABLE)) || errno ||
117 ((errno = 0), prctl(PR_SET_DUMPABLE, 1)) || errno ||
118 ((errno = 0), !prctl(PR_SET_SECCOMP, 0)) || errno != ERR) {
119 perror("prctl()");
120 _exit(1);
121 }
122
123 // Check that we can send and receive file handles.
124 int fds[3];
125 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
126 perror("socketpair()");
127 _exit(1);
128 }
129 size_t len = 4;
130 char buf[4];
131 if (!playground2::Util::sendFds(fds[0], "test", 4, fds[1], -1) ||
132 !playground2::Util::getFds(fds[1], buf, &len, fds+2, NULL) ||
133 len != 4 ||
134 memcmp(buf, "test", len) ||
135 write(fds[2], "demo", 4) != 4 ||
136 read(fds[0], buf, 4) != 4 ||
137 memcmp(buf, "demo", 4) ||
138 close(fds[0]) ||
139 close(fds[1]) ||
140 close(fds[2])) {
141 perror("sending/receiving of fds");
142 _exit(1);
143 }
144
145 // Check whether SysV IPC works.
146 int shmid;
147 void *addr;
148 if ((shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT|0600)) < 0 ||
149 (addr = shmat(shmid, NULL, 0)) == (void *)-1 ||
150 shmdt(addr) ||
151 shmctl(shmid, IPC_RMID, NULL)) {
152 perror("sysv IPC");
153 _exit(1);
154 }
155
156 // Print a message so that the user can see the sandbox is activated.
157 time_t tm = time(NULL);
158 printf("Sandbox has been started at %s", ctime(&tm));
159
160 // Stress-test the sendmsg() code
161 static const int sendmsgStressNumThreads = 10;
162 pthread_t sendmsgStressThreads[sendmsgStressNumThreads];
163 for (int i = 0; i < sendmsgStressNumThreads; ++i) {
164 if (pthread_create(sendmsgStressThreads + i, NULL,
165 sendmsgStressThreadFnc, NULL)) {
166 perror("pthread_create");
167 _exit(1);
168 }
169 }
170 for (int i = 0; i < sendmsgStressNumThreads; ++i) {
171 pthread_join(sendmsgStressThreads[i], NULL);
172 }
173
174 return 0;
175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698