diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/Makefile.in | 2 | ||||
-rw-r--r-- | src/firejail/errno.c | 11 | ||||
-rw-r--r-- | src/firejail/firejail.h | 7 | ||||
-rw-r--r-- | src/firejail/join.c | 2 | ||||
-rw-r--r-- | src/firejail/main.c | 22 | ||||
-rw-r--r-- | src/firejail/profile.c | 14 | ||||
-rw-r--r-- | src/firejail/protocol.c | 247 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 20 | ||||
-rw-r--r-- | src/firejail/sbox.c | 6 | ||||
-rw-r--r-- | src/firejail/syscall.c | 13 | ||||
-rw-r--r-- | src/include/syscall.h (renamed from src/firejail/syscall.h) | 1 |
11 files changed, 81 insertions, 264 deletions
diff --git a/src/firejail/Makefile.in b/src/firejail/Makefile.in index c4c168236..c99b6c30c 100644 --- a/src/firejail/Makefile.in +++ b/src/firejail/Makefile.in | |||
@@ -30,7 +30,7 @@ BINOBJS = $(foreach file, $(OBJS), $file) | |||
30 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | 30 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security |
31 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread | 31 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread |
32 | 32 | ||
33 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h | 33 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h ../include/syscall.h |
34 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | 34 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ |
35 | 35 | ||
36 | firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o | 36 | firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o |
diff --git a/src/firejail/errno.c b/src/firejail/errno.c index c493dfa09..03f10bb14 100644 --- a/src/firejail/errno.c +++ b/src/firejail/errno.c | |||
@@ -206,15 +206,4 @@ char *errno_find_nr(int nr) { | |||
206 | return "unknown"; | 206 | return "unknown"; |
207 | } | 207 | } |
208 | 208 | ||
209 | void errno_print(void) { | ||
210 | EUID_ASSERT(); | ||
211 | |||
212 | int i; | ||
213 | int elems = sizeof(errnolist) / sizeof(errnolist[0]); | ||
214 | for (i = 0; i < elems; i++) { | ||
215 | printf("%d\t- %s\n", errnolist[i].nr, errnolist[i].name); | ||
216 | } | ||
217 | printf("\n"); | ||
218 | } | ||
219 | |||
220 | #endif // HAVE_SECCOMP | 209 | #endif // HAVE_SECCOMP |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 367f599ec..749656f8b 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define RUN_RO_FILE "/run/firejail/firejail.ro.file" | 39 | #define RUN_RO_FILE "/run/firejail/firejail.ro.file" |
40 | #define RUN_MNT_DIR "/run/firejail/mnt" // a tmpfs is mounted on this directory before any of the files below are created | 40 | #define RUN_MNT_DIR "/run/firejail/mnt" // a tmpfs is mounted on this directory before any of the files below are created |
41 | #define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" | 41 | #define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" |
42 | #define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" | ||
42 | #define RUN_CGROUP_CFG "/run/firejail/mnt/cgroup" | 43 | #define RUN_CGROUP_CFG "/run/firejail/mnt/cgroup" |
43 | #define RUN_CPU_CFG "/run/firejail/mnt/cpu" | 44 | #define RUN_CPU_CFG "/run/firejail/mnt/cpu" |
44 | #define RUN_GROUPS_CFG "/run/firejail/mnt/groups" | 45 | #define RUN_GROUPS_CFG "/run/firejail/mnt/groups" |
@@ -514,8 +515,6 @@ void caps_print_filter_name(const char *name); | |||
514 | const char *syscall_find_nr(int nr); | 515 | const char *syscall_find_nr(int nr); |
515 | // return -1 if error, 0 if no error | 516 | // return -1 if error, 0 if no error |
516 | int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg); | 517 | int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg); |
517 | // print all available syscallsseccomp | ||
518 | void syscall_print(void); | ||
519 | 518 | ||
520 | // fs_trace.c | 519 | // fs_trace.c |
521 | void fs_trace_preload(void); | 520 | void fs_trace_preload(void); |
@@ -598,7 +597,7 @@ void protocol_list(); | |||
598 | void protocol_print_filter_name(const char *name); | 597 | void protocol_print_filter_name(const char *name); |
599 | void protocol_print_filter(pid_t pid); | 598 | void protocol_print_filter(pid_t pid); |
600 | void protocol_store(const char *prlist); | 599 | void protocol_store(const char *prlist); |
601 | void protocol_filter(void); | 600 | void protocol_filter(const char *fname); |
602 | void protocol_filter_save(void); | 601 | void protocol_filter_save(void); |
603 | void protocol_filter_load(const char *fname); | 602 | void protocol_filter_load(const char *fname); |
604 | 603 | ||
@@ -686,11 +685,13 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar | |||
686 | // programs | 685 | // programs |
687 | #define PATH_FNET (LIBDIR "/firejail/fnet") | 686 | #define PATH_FNET (LIBDIR "/firejail/fnet") |
688 | #define PATH_FIREMON (PREFIX "/bin/firemon") | 687 | #define PATH_FIREMON (PREFIX "/bin/firemon") |
688 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") | ||
689 | // bitmapped filters for sbox_run | 689 | // bitmapped filters for sbox_run |
690 | #define SBOX_ROOT 1 | 690 | #define SBOX_ROOT 1 |
691 | #define SBOX_USER 2 | 691 | #define SBOX_USER 2 |
692 | #define SBOX_CAPS 4 | 692 | #define SBOX_CAPS 4 |
693 | #define SBOX_SECCOMP 8 | 693 | #define SBOX_SECCOMP 8 |
694 | // run sbox | ||
694 | int sbox_run(unsigned filter, int num, ...); | 695 | int sbox_run(unsigned filter, int num, ...); |
695 | 696 | ||
696 | 697 | ||
diff --git a/src/firejail/join.c b/src/firejail/join.c index ea44019ca..9b5fba24d 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -296,7 +296,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
296 | if (getuid() != 0) | 296 | if (getuid() != 0) |
297 | protocol_filter_load(RUN_PROTOCOL_CFG); | 297 | protocol_filter_load(RUN_PROTOCOL_CFG); |
298 | if (cfg.protocol) { // not available for uid 0 | 298 | if (cfg.protocol) { // not available for uid 0 |
299 | protocol_filter(); | 299 | protocol_filter(RUN_SECCOMP_PROTOCOL); |
300 | } | 300 | } |
301 | 301 | ||
302 | // set seccomp filter | 302 | // set seccomp filter |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 15d42a4e0..e210ceb31 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -404,8 +404,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
404 | #ifdef HAVE_SECCOMP | 404 | #ifdef HAVE_SECCOMP |
405 | else if (strcmp(argv[i], "--debug-syscalls") == 0) { | 405 | else if (strcmp(argv[i], "--debug-syscalls") == 0) { |
406 | if (checkcfg(CFG_SECCOMP)) { | 406 | if (checkcfg(CFG_SECCOMP)) { |
407 | syscall_print(); | 407 | int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-syscalls"); |
408 | exit(0); | 408 | exit(rv); |
409 | } | 409 | } |
410 | else { | 410 | else { |
411 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | 411 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); |
@@ -414,7 +414,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
414 | } | 414 | } |
415 | else if (strcmp(argv[i], "--debug-errnos") == 0) { | 415 | else if (strcmp(argv[i], "--debug-errnos") == 0) { |
416 | if (checkcfg(CFG_SECCOMP)) { | 416 | if (checkcfg(CFG_SECCOMP)) { |
417 | errno_print(); | 417 | int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-errnos"); |
418 | exit(rv); | ||
418 | } | 419 | } |
419 | else { | 420 | else { |
420 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | 421 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); |
@@ -438,8 +439,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
438 | exit(0); | 439 | exit(0); |
439 | } | 440 | } |
440 | else if (strcmp(argv[i], "--debug-protocols") == 0) { | 441 | else if (strcmp(argv[i], "--debug-protocols") == 0) { |
441 | protocol_list(); | 442 | int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-protocols"); |
442 | exit(0); | 443 | exit(rv); |
443 | } | 444 | } |
444 | else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { | 445 | else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { |
445 | if (checkcfg(CFG_SECCOMP)) { | 446 | if (checkcfg(CFG_SECCOMP)) { |
@@ -1117,7 +1118,16 @@ int main(int argc, char **argv) { | |||
1117 | #ifdef HAVE_SECCOMP | 1118 | #ifdef HAVE_SECCOMP |
1118 | else if (strncmp(argv[i], "--protocol=", 11) == 0) { | 1119 | else if (strncmp(argv[i], "--protocol=", 11) == 0) { |
1119 | if (checkcfg(CFG_SECCOMP)) { | 1120 | if (checkcfg(CFG_SECCOMP)) { |
1120 | protocol_store(argv[i] + 11); | 1121 | if (cfg.protocol) { |
1122 | if (!arg_quiet) | ||
1123 | fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", argv[i] + 11); | ||
1124 | } | ||
1125 | else { | ||
1126 | // store list | ||
1127 | cfg.protocol = strdup(argv[i] + 11); | ||
1128 | if (!cfg.protocol) | ||
1129 | errExit("strdup"); | ||
1130 | } | ||
1121 | } | 1131 | } |
1122 | else { | 1132 | else { |
1123 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | 1133 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index e5c35a89d..f7d5e87e6 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -497,8 +497,18 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
497 | 497 | ||
498 | if (strncmp(ptr, "protocol ", 9) == 0) { | 498 | if (strncmp(ptr, "protocol ", 9) == 0) { |
499 | #ifdef HAVE_SECCOMP | 499 | #ifdef HAVE_SECCOMP |
500 | if (checkcfg(CFG_SECCOMP)) | 500 | if (checkcfg(CFG_SECCOMP)) { |
501 | protocol_store(ptr + 9); | 501 | if (cfg.protocol) { |
502 | if (!arg_quiet) | ||
503 | fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", ptr + 9); | ||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | // store list | ||
508 | cfg.protocol = strdup(ptr + 9); | ||
509 | if (!cfg.protocol) | ||
510 | errExit("strdup"); | ||
511 | } | ||
502 | else | 512 | else |
503 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); | 513 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); |
504 | #endif | 514 | #endif |
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c index 6321c703a..43f30e30a 100644 --- a/src/firejail/protocol.c +++ b/src/firejail/protocol.c | |||
@@ -18,241 +18,44 @@ | |||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /* | ||
22 | struct sock_filter filter[] = { | ||
23 | VALIDATE_ARCHITECTURE, | ||
24 | EXAMINE_SYSCALL, | ||
25 | ONLY(SYS_socket), | ||
26 | EXAMINE_ARGUMENT(0), // allow only AF_INET and AF_INET6, drop everything else | ||
27 | WHITELIST(AF_INET), | ||
28 | WHITELIST(AF_INET6), | ||
29 | WHITELIST(AF_PACKET), | ||
30 | RETURN_ERRNO(ENOTSUP) | ||
31 | }; | ||
32 | struct sock_fprog prog = { | ||
33 | .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), | ||
34 | .filter = filter, | ||
35 | }; | ||
36 | |||
37 | |||
38 | if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | ||
39 | perror("prctl(NO_NEW_PRIVS)"); | ||
40 | return 1; | ||
41 | } | ||
42 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { | ||
43 | perror("prctl"); | ||
44 | return 1; | ||
45 | } | ||
46 | */ | ||
47 | |||
48 | #ifdef HAVE_SECCOMP | 21 | #ifdef HAVE_SECCOMP |
49 | #include "firejail.h" | 22 | #include "firejail.h" |
50 | #include "../include/seccomp.h" | 23 | #include "../include/seccomp.h" |
51 | #include <sys/types.h> | ||
52 | #include <sys/socket.h> | ||
53 | |||
54 | static char *protocol[] = { | ||
55 | "unix", | ||
56 | "inet", | ||
57 | "inet6", | ||
58 | "netlink", | ||
59 | "packet", | ||
60 | NULL | ||
61 | }; | ||
62 | |||
63 | static struct sock_filter protocol_filter_command[] = { | ||
64 | WHITELIST(AF_UNIX), | ||
65 | WHITELIST(AF_INET), | ||
66 | WHITELIST(AF_INET6), | ||
67 | WHITELIST(AF_NETLINK), | ||
68 | WHITELIST(AF_PACKET) | ||
69 | }; | ||
70 | // Note: protocol[] and protocol_filter_command are synchronized | ||
71 | |||
72 | // command length | ||
73 | struct sock_filter whitelist[] = { | ||
74 | WHITELIST(AF_UNIX) | ||
75 | }; | ||
76 | unsigned whitelist_len = sizeof(whitelist) / sizeof(struct sock_filter); | ||
77 | |||
78 | 24 | ||
79 | 25 | // install protocol filter | |
80 | static int is_protocol(const char *p) { | 26 | void protocol_filter(const char *fname) { |
81 | int i = 0; | ||
82 | while (protocol[i] != NULL) { | ||
83 | if (strcmp(protocol[i], p) == 0) | ||
84 | return 1; | ||
85 | i++; | ||
86 | } | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static struct sock_filter *find_protocol_domain(const char *p) { | ||
92 | int i = 0; | ||
93 | while (protocol[i] != NULL) { | ||
94 | if (strcmp(protocol[i], p) == 0) | ||
95 | return &protocol_filter_command[i * whitelist_len]; | ||
96 | i++; | ||
97 | } | ||
98 | |||
99 | return NULL; | ||
100 | } | ||
101 | |||
102 | // --debug-protocols | ||
103 | void protocol_list(void) { | ||
104 | EUID_ASSERT(); | ||
105 | |||
106 | #ifndef SYS_socket | 27 | #ifndef SYS_socket |
107 | fprintf(stderr, "Warning: --protocol not supported on this platform\n"); | 28 | if (arg_debug) |
29 | printf("No support for --protocol on this platform\n"); | ||
108 | return; | 30 | return; |
109 | #endif | 31 | #else |
110 | 32 | assert(fname); | |
111 | int i = 0; | ||
112 | while (protocol[i] != NULL) { | ||
113 | printf("%s, ", protocol[i]); | ||
114 | i++; | ||
115 | } | ||
116 | printf("\n"); | ||
117 | } | ||
118 | |||
119 | 33 | ||
120 | // check protocol list and store it in cfg structure | 34 | // check file |
121 | void protocol_store(const char *prlist) { | 35 | struct stat s; |
122 | EUID_ASSERT(); | 36 | if (stat(fname, &s) == -1) { |
123 | assert(prlist); | 37 | fprintf(stderr, "Error: cannot read protocol filter file\n"); |
124 | 38 | exit(1); | |
125 | if (cfg.protocol && !arg_quiet) { | ||
126 | fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", prlist); | ||
127 | return; | ||
128 | } | 39 | } |
129 | 40 | int size = s.st_size; | |
130 | // temporary list | ||
131 | char *tmplist = strdup(prlist); | ||
132 | if (!tmplist) | ||
133 | errExit("strdup"); | ||
134 | |||
135 | // check list | ||
136 | char *token = strtok(tmplist, ","); | ||
137 | if (!token) | ||
138 | goto errout; | ||
139 | |||
140 | while (token) { | ||
141 | if (!is_protocol(token)) | ||
142 | goto errout; | ||
143 | token = strtok(NULL, ","); | ||
144 | } | ||
145 | free(tmplist); | ||
146 | |||
147 | // store list | ||
148 | cfg.protocol = strdup(prlist); | ||
149 | if (!cfg.protocol) | ||
150 | errExit("strdup"); | ||
151 | return; | ||
152 | |||
153 | errout: | ||
154 | fprintf(stderr, "Error: invalid protocol list\n"); | ||
155 | exit(1); | ||
156 | } | ||
157 | 41 | ||
158 | // install protocol filter | 42 | // read filter |
159 | void protocol_filter(void) { | ||
160 | assert(cfg.protocol); | ||
161 | if (arg_debug) | ||
162 | printf("Set protocol filter: %s\n", cfg.protocol); | ||
163 | |||
164 | #ifndef SYS_socket | ||
165 | (void) find_protocol_domain; | ||
166 | fprintf(stderr, "Warning: --protocol not supported on this platform\n"); | ||
167 | return; | ||
168 | #else | ||
169 | // build the filter | ||
170 | struct sock_filter filter[32]; // big enough | 43 | struct sock_filter filter[32]; // big enough |
171 | memset(&filter[0], 0, sizeof(filter)); | 44 | memset(&filter[0], 0, sizeof(filter)); |
172 | uint8_t *ptr = (uint8_t *) &filter[0]; | 45 | int src = open(fname, O_RDONLY); |
173 | 46 | int rd = 0; | |
174 | // header | 47 | while (rd < size) { |
175 | struct sock_filter filter_start[] = { | 48 | int rv = read(src, (unsigned char *) filter + rd, size - rd); |
176 | VALIDATE_ARCHITECTURE, | 49 | if (rv == -1) { |
177 | EXAMINE_SYSCALL, | 50 | fprintf(stderr, "Error: cannot read %s file\n", fname); |
178 | ONLY(SYS_socket), | 51 | exit(1); |
179 | EXAMINE_ARGUMENT(0) | 52 | } |
180 | }; | 53 | rd += rv; |
181 | memcpy(ptr, &filter_start[0], sizeof(filter_start)); | ||
182 | ptr += sizeof(filter_start); | ||
183 | |||
184 | #if 0 | ||
185 | printf("entries %u\n", (unsigned) (sizeof(filter_start) / sizeof(struct sock_filter))); | ||
186 | { | ||
187 | unsigned j; | ||
188 | unsigned char *ptr2 = (unsigned char *) &filter[0]; | ||
189 | for (j = 0; j < sizeof(filter); j++, ptr2++) { | ||
190 | if ((j % (sizeof(struct sock_filter))) == 0) | ||
191 | printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter)))); | ||
192 | printf("%02x, ", (*ptr2) & 0xff); | ||
193 | } | ||
194 | printf("\n"); | ||
195 | } | ||
196 | printf("whitelist_len %u, struct sock_filter len %u\n", whitelist_len, (unsigned) sizeof(struct sock_filter)); | ||
197 | #endif | ||
198 | |||
199 | |||
200 | // parse list and add commands | ||
201 | char *tmplist = strdup(cfg.protocol); | ||
202 | if (!tmplist) | ||
203 | errExit("strdup"); | ||
204 | char *token = strtok(tmplist, ","); | ||
205 | if (!token) | ||
206 | errExit("strtok"); | ||
207 | |||
208 | while (token) { | ||
209 | struct sock_filter *domain = find_protocol_domain(token); | ||
210 | assert(domain); | ||
211 | memcpy(ptr, domain, whitelist_len * sizeof(struct sock_filter)); | ||
212 | ptr += whitelist_len * sizeof(struct sock_filter); | ||
213 | token = strtok(NULL, ","); | ||
214 | |||
215 | #if 0 | ||
216 | printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter)); | ||
217 | { | ||
218 | unsigned j; | ||
219 | unsigned char *ptr2 = (unsigned char *) &filter[0]; | ||
220 | for (j = 0; j < sizeof(filter); j++, ptr2++) { | ||
221 | if ((j % (sizeof(struct sock_filter))) == 0) | ||
222 | printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter)))); | ||
223 | printf("%02x, ", (*ptr2) & 0xff); | ||
224 | } | ||
225 | printf("\n"); | ||
226 | } | ||
227 | #endif | ||
228 | |||
229 | |||
230 | } | ||
231 | free(tmplist); | ||
232 | |||
233 | // add end of filter | ||
234 | struct sock_filter filter_end[] = { | ||
235 | RETURN_ERRNO(ENOTSUP) | ||
236 | }; | ||
237 | memcpy(ptr, &filter_end[0], sizeof(filter_end)); | ||
238 | ptr += sizeof(filter_end); | ||
239 | |||
240 | #if 0 | ||
241 | printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter)); | ||
242 | { | ||
243 | unsigned j; | ||
244 | unsigned char *ptr2 = (unsigned char *) &filter[0]; | ||
245 | for (j = 0; j < sizeof(filter); j++, ptr2++) { | ||
246 | if ((j % (sizeof(struct sock_filter))) == 0) | ||
247 | printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter)))); | ||
248 | printf("%02x, ", (*ptr2) & 0xff); | ||
249 | } | 54 | } |
250 | printf("\n"); | 55 | close(src); |
251 | } | ||
252 | #endif | ||
253 | 56 | ||
254 | // install filter | 57 | // install filter |
255 | unsigned short entries = (unsigned short) ((uintptr_t) ptr - (uintptr_t) (filter)) / (unsigned) sizeof(struct sock_filter); | 58 | unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter); |
256 | struct sock_fprog prog = { | 59 | struct sock_fprog prog = { |
257 | .len = entries, | 60 | .len = entries, |
258 | .filter = filter, | 61 | .filter = filter, |
@@ -262,7 +65,7 @@ printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (uns | |||
262 | fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); | 65 | fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); |
263 | return; | 66 | return; |
264 | } | 67 | } |
265 | #endif // SYS_socket | 68 | #endif |
266 | } | 69 | } |
267 | 70 | ||
268 | void protocol_filter_save(void) { | 71 | void protocol_filter_save(void) { |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index f5cca7494..7a63461ef 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -819,8 +819,24 @@ int sandbox(void* sandbox_arg) { | |||
819 | #ifdef HAVE_SECCOMP | 819 | #ifdef HAVE_SECCOMP |
820 | // install protocol filter | 820 | // install protocol filter |
821 | if (cfg.protocol) { | 821 | if (cfg.protocol) { |
822 | protocol_filter(); // install filter | 822 | if (arg_debug) |
823 | protocol_filter_save(); // save filter in PROTOCOL_CFG | 823 | printf("Set protocol filter: %s\n", cfg.protocol); |
824 | // as root, create RUN_SECCOMP_PROTOCOL file | ||
825 | // this is where fseccomp program will store the protocol filter | ||
826 | int dst = open(RUN_SECCOMP_PROTOCOL, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
827 | if (dst == -1) | ||
828 | errExit("open"); | ||
829 | close(dst); | ||
830 | if (chown(RUN_SECCOMP_PROTOCOL, getuid(), getgid()) == -1) | ||
831 | errExit("chown"); | ||
832 | |||
833 | // build the seccomp filter as a regular user | ||
834 | int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 5, | ||
835 | PATH_FSECCOMP, "protocol", "build", cfg.protocol, RUN_SECCOMP_PROTOCOL); | ||
836 | if (rv) | ||
837 | exit(rv); | ||
838 | protocol_filter(RUN_SECCOMP_PROTOCOL); // install filter | ||
839 | protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG | ||
824 | } | 840 | } |
825 | 841 | ||
826 | // if a keep list is available, disregard the drop list | 842 | // if a keep list is available, disregard the drop list |
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index 8c6ace27e..d3ef2578c 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c | |||
@@ -124,14 +124,14 @@ int sbox_run(unsigned filter, int num, ...) { | |||
124 | arg[i] = NULL; | 124 | arg[i] = NULL; |
125 | va_end(valist); | 125 | va_end(valist); |
126 | 126 | ||
127 | #if 0 | 127 | //#if 0 |
128 | { | 128 | { |
129 | int i; | 129 | int i; |
130 | for (i = 0; i <= num; i++) | 130 | for (i = 0; i <= num; i++) |
131 | printf("#%s# ", arg[i]); | 131 | printf("#%s# ", arg[i]); |
132 | printf("\n"); | 132 | printf("\n"); |
133 | } | 133 | } |
134 | #endif | 134 | //#endif |
135 | pid_t child = fork(); | 135 | pid_t child = fork(); |
136 | if (child < 0) | 136 | if (child < 0) |
137 | errExit("fork"); | 137 | errExit("fork"); |
@@ -169,7 +169,7 @@ printf("\n"); | |||
169 | errExit("waitpid"); | 169 | errExit("waitpid"); |
170 | } | 170 | } |
171 | if (WIFEXITED(status) && status != 0) { | 171 | if (WIFEXITED(status) && status != 0) { |
172 | fprintf(stderr, "Error: cannot run fnet\n"); | 172 | fprintf(stderr, "Error: failed to run %s\n", arg[0]); |
173 | exit(1); | 173 | exit(1); |
174 | } | 174 | } |
175 | 175 | ||
diff --git a/src/firejail/syscall.c b/src/firejail/syscall.c index 985cc8bb8..f405f23c8 100644 --- a/src/firejail/syscall.c +++ b/src/firejail/syscall.c | |||
@@ -31,7 +31,7 @@ static SyscallEntry syslist[] = { | |||
31 | // | 31 | // |
32 | // code generated using tools/extract-syscall | 32 | // code generated using tools/extract-syscall |
33 | // | 33 | // |
34 | #include "syscall.h" | 34 | #include "../include/syscall.h" |
35 | // | 35 | // |
36 | // end of generated code | 36 | // end of generated code |
37 | // | 37 | // |
@@ -102,15 +102,4 @@ int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg) | |||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | void syscall_print(void) { | ||
106 | EUID_ASSERT(); | ||
107 | |||
108 | int i; | ||
109 | int elems = sizeof(syslist) / sizeof(syslist[0]); | ||
110 | for (i = 0; i < elems; i++) { | ||
111 | printf("%d\t- %s\n", syslist[i].nr, syslist[i].name); | ||
112 | } | ||
113 | printf("\n"); | ||
114 | } | ||
115 | |||
116 | #endif // HAVE_SECCOMP | 105 | #endif // HAVE_SECCOMP |
diff --git a/src/firejail/syscall.h b/src/include/syscall.h index 68d4b5736..9a29779c9 100644 --- a/src/firejail/syscall.h +++ b/src/include/syscall.h | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | // content extracted from /bits/syscall.h file form glibc 2.22 | 21 | // content extracted from /bits/syscall.h file form glibc 2.22 |
22 | // using ../tools/extract_syscall tool | 22 | // using ../tools/extract_syscall tool |
23 | |||
24 | #if !defined __x86_64__ | 23 | #if !defined __x86_64__ |
25 | #ifdef SYS__llseek | 24 | #ifdef SYS__llseek |
26 | #ifdef __NR__llseek | 25 | #ifdef __NR__llseek |