diff options
Diffstat (limited to 'src/fseccomp')
-rw-r--r-- | src/fseccomp/Makefile.in | 4 | ||||
-rw-r--r-- | src/fseccomp/errno.c | 43 | ||||
-rw-r--r-- | src/fseccomp/fseccomp.h | 50 | ||||
-rw-r--r-- | src/fseccomp/main.c | 49 | ||||
-rw-r--r-- | src/fseccomp/seccomp.c | 292 | ||||
-rw-r--r-- | src/fseccomp/seccomp_file.c | 108 | ||||
-rw-r--r-- | src/fseccomp/seccomp_print.c | 116 | ||||
-rw-r--r-- | src/fseccomp/seccomp_secondary.c | 183 | ||||
-rw-r--r-- | src/fseccomp/syscall.c | 84 |
9 files changed, 927 insertions, 2 deletions
diff --git a/src/fseccomp/Makefile.in b/src/fseccomp/Makefile.in index e7edd1b8f..110d2c95f 100644 --- a/src/fseccomp/Makefile.in +++ b/src/fseccomp/Makefile.in | |||
@@ -30,11 +30,11 @@ 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/libnetlink.h ../include/pid.h ../include/syscall.h | 33 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h |
34 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | 34 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ |
35 | 35 | ||
36 | fseccomp: $(OBJS) ../lib/libnetlink.o ../lib/common.o | 36 | fseccomp: $(OBJS) ../lib/libnetlink.o ../lib/common.o |
37 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS) | 37 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) |
38 | 38 | ||
39 | clean:; rm -f *.o fseccomp | 39 | clean:; rm -f *.o fseccomp |
40 | 40 | ||
diff --git a/src/fseccomp/errno.c b/src/fseccomp/errno.c index 625f484bd..dbee916d4 100644 --- a/src/fseccomp/errno.c +++ b/src/fseccomp/errno.c | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
1 | #include "fseccomp.h" | 20 | #include "fseccomp.h" |
2 | 21 | ||
3 | #include <errno.h> | 22 | #include <errno.h> |
@@ -151,6 +170,30 @@ static ErrnoEntry errnolist[] = { | |||
151 | #endif | 170 | #endif |
152 | }; | 171 | }; |
153 | 172 | ||
173 | int errno_find_name(const char *name) { | ||
174 | int i; | ||
175 | int elems = sizeof(errnolist) / sizeof(errnolist[0]); | ||
176 | for (i = 0; i < elems; i++) { | ||
177 | if (strcasecmp(name, errnolist[i].name) == 0) | ||
178 | return errnolist[i].nr; | ||
179 | } | ||
180 | |||
181 | return -1; | ||
182 | } | ||
183 | |||
184 | char *errno_find_nr(int nr) { | ||
185 | int i; | ||
186 | int elems = sizeof(errnolist) / sizeof(errnolist[0]); | ||
187 | for (i = 0; i < elems; i++) { | ||
188 | if (nr == errnolist[i].nr) | ||
189 | return errnolist[i].name; | ||
190 | } | ||
191 | |||
192 | return "unknown"; | ||
193 | } | ||
194 | |||
195 | |||
196 | |||
154 | void errno_print(void) { | 197 | void errno_print(void) { |
155 | int i; | 198 | int i; |
156 | int elems = sizeof(errnolist) / sizeof(errnolist[0]); | 199 | int elems = sizeof(errnolist) / sizeof(errnolist[0]); |
diff --git a/src/fseccomp/fseccomp.h b/src/fseccomp/fseccomp.h index 57757ea6c..504f1c23f 100644 --- a/src/fseccomp/fseccomp.h +++ b/src/fseccomp/fseccomp.h | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
1 | #ifndef FSECCOMP_H | 20 | #ifndef FSECCOMP_H |
2 | #define FSECCOMP_H | 21 | #define FSECCOMP_H |
3 | #include <stdio.h> | 22 | #include <stdio.h> |
@@ -8,11 +27,42 @@ | |||
8 | 27 | ||
9 | // syscall.c | 28 | // syscall.c |
10 | void syscall_print(void); | 29 | void syscall_print(void); |
30 | int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg); | ||
31 | int syscall_find_name(const char *name); | ||
32 | char *syscall_find_nr(int nr); | ||
11 | 33 | ||
12 | // errno.c | 34 | // errno.c |
13 | void errno_print(void); | 35 | void errno_print(void); |
36 | int errno_find_name(const char *name); | ||
37 | char *errno_find_nr(int nr); | ||
14 | 38 | ||
15 | // protocol.c | 39 | // protocol.c |
16 | void protocol_print(void); | 40 | void protocol_print(void); |
17 | void protocol_build_filter(const char *prlist, const char *fname); | 41 | void protocol_build_filter(const char *prlist, const char *fname); |
42 | |||
43 | // seccomp_secondary.c | ||
44 | void seccomp_secondary_64(const char *fname); | ||
45 | void seccomp_secondary_32(const char *fname); | ||
46 | |||
47 | // seccomp_file.c | ||
48 | void filter_init(int fd); | ||
49 | void filter_add_whitelist(int fd, int syscall, int arg); | ||
50 | void filter_add_blacklist(int fd, int syscall, int arg); | ||
51 | void filter_add_errno(int fd, int syscall, int arg); | ||
52 | void filter_end_blacklist(int fd); | ||
53 | void filter_end_whitelist(int fd); | ||
54 | |||
55 | // seccomp.c | ||
56 | // default list | ||
57 | void seccomp_default(const char *fname, int allow_debuggers); | ||
58 | // drop list | ||
59 | void seccomp_drop(const char *fname, char *list, int allow_debuggers); | ||
60 | // default+drop list | ||
61 | void seccomp_default_drop(const char *fname, char *list, int allow_debuggers); | ||
62 | // whitelisted filter | ||
63 | void seccomp_keep(const char *fname, char *list); | ||
64 | |||
65 | // seccomp_print | ||
66 | void filter_print(const char *fname); | ||
67 | |||
18 | #endif | 68 | #endif |
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c index f53e2ef8b..22b13bcd9 100644 --- a/src/fseccomp/main.c +++ b/src/fseccomp/main.c | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
1 | #include "fseccomp.h" | 20 | #include "fseccomp.h" |
2 | 21 | ||
3 | static void usage(void) { | 22 | static void usage(void) { |
@@ -6,6 +25,16 @@ static void usage(void) { | |||
6 | printf("\tfseccomp debug-errnos\n"); | 25 | printf("\tfseccomp debug-errnos\n"); |
7 | printf("\tfseccomp debug-protocols\n"); | 26 | printf("\tfseccomp debug-protocols\n"); |
8 | printf("\tfseccomp protocol build list file\n"); | 27 | printf("\tfseccomp protocol build list file\n"); |
28 | printf("\tfseccomp secondary 64 file\n"); | ||
29 | printf("\tfseccomp secondary 32 file\n"); | ||
30 | printf("\tfseccomp default file\n"); | ||
31 | printf("\tfseccomp default file allow-debuggers\n"); | ||
32 | printf("\tfseccomp drop file list\n"); | ||
33 | printf("\tfseccomp drop file list allow-debuggers\n"); | ||
34 | printf("\tfseccomp default drop file list\n"); | ||
35 | printf("\tfseccomp default drop file list allow-debuggers\n"); | ||
36 | printf("\tfseccomp keep file list\n"); | ||
37 | printf("\tfseccomp print file\n"); | ||
9 | } | 38 | } |
10 | 39 | ||
11 | int main(int argc, char **argv) { | 40 | int main(int argc, char **argv) { |
@@ -33,6 +62,26 @@ printf("\n"); | |||
33 | protocol_print(); | 62 | protocol_print(); |
34 | else if (argc == 5 && strcmp(argv[1], "protocol") == 0 && strcmp(argv[2], "build") == 0) | 63 | else if (argc == 5 && strcmp(argv[1], "protocol") == 0 && strcmp(argv[2], "build") == 0) |
35 | protocol_build_filter(argv[3], argv[4]); | 64 | protocol_build_filter(argv[3], argv[4]); |
65 | else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "64") == 0) | ||
66 | seccomp_secondary_64(argv[3]); | ||
67 | else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "32") == 0) | ||
68 | seccomp_secondary_32(argv[3]); | ||
69 | else if (argc == 3 && strcmp(argv[1], "default") == 0) | ||
70 | seccomp_default(argv[2], 0); | ||
71 | else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0) | ||
72 | seccomp_default(argv[2], 1); | ||
73 | else if (argc == 4 && strcmp(argv[1], "drop") == 0) | ||
74 | seccomp_drop(argv[2], argv[3], 0); | ||
75 | else if (argc == 5 && strcmp(argv[1], "drop") == 0 && strcmp(argv[4], "allow-debuggers") == 0) | ||
76 | seccomp_drop(argv[2], argv[3], 1); | ||
77 | else if (argc == 5 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0) | ||
78 | seccomp_default_drop(argv[3], argv[4], 0); | ||
79 | else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0) | ||
80 | seccomp_default_drop(argv[3], argv[4], 1); | ||
81 | else if (argc == 4 && strcmp(argv[1], "keep") == 0) | ||
82 | seccomp_keep(argv[2], argv[3]); | ||
83 | else if (argc == 3 && strcmp(argv[1], "print") == 0) | ||
84 | filter_print(argv[2]); | ||
36 | else { | 85 | else { |
37 | fprintf(stderr, "Error fseccomp: invalid arguments\n"); | 86 | fprintf(stderr, "Error fseccomp: invalid arguments\n"); |
38 | return 1; | 87 | return 1; |
diff --git a/src/fseccomp/seccomp.c b/src/fseccomp/seccomp.c new file mode 100644 index 000000000..cc6edc8ca --- /dev/null +++ b/src/fseccomp/seccomp.c | |||
@@ -0,0 +1,292 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "fseccomp.h" | ||
21 | #include "../include/seccomp.h" | ||
22 | #include <sys/syscall.h> | ||
23 | |||
24 | static void add_default_list(int fd, int allow_debuggers) { | ||
25 | #ifdef SYS_mount | ||
26 | filter_add_blacklist(fd, SYS_mount, 0); | ||
27 | #endif | ||
28 | #ifdef SYS_umount2 | ||
29 | filter_add_blacklist(fd, SYS_umount2, 0); | ||
30 | #endif | ||
31 | |||
32 | if (!allow_debuggers) { | ||
33 | #ifdef SYS_ptrace | ||
34 | filter_add_blacklist(fd, SYS_ptrace, 0); | ||
35 | #endif | ||
36 | } | ||
37 | |||
38 | #ifdef SYS_kexec_load | ||
39 | filter_add_blacklist(fd, SYS_kexec_load, 0); | ||
40 | #endif | ||
41 | #ifdef SYS_kexec_file_load | ||
42 | filter_add_blacklist(fd, SYS_kexec_file_load, 0); | ||
43 | #endif | ||
44 | #ifdef SYS_open_by_handle_at | ||
45 | filter_add_blacklist(fd, SYS_open_by_handle_at, 0); | ||
46 | #endif | ||
47 | #ifdef SYS_name_to_handle_at | ||
48 | filter_add_blacklist(fd, SYS_name_to_handle_at, 0); | ||
49 | #endif | ||
50 | #ifdef SYS_init_module | ||
51 | filter_add_blacklist(fd, SYS_init_module, 0); | ||
52 | #endif | ||
53 | #ifdef SYS_finit_module | ||
54 | filter_add_blacklist(fd, SYS_finit_module, 0); | ||
55 | #endif | ||
56 | #ifdef SYS_create_module | ||
57 | filter_add_blacklist(fd, SYS_create_module, 0); | ||
58 | #endif | ||
59 | #ifdef SYS_delete_module | ||
60 | filter_add_blacklist(fd, SYS_delete_module, 0); | ||
61 | #endif | ||
62 | #ifdef SYS_iopl | ||
63 | filter_add_blacklist(fd, SYS_iopl, 0); | ||
64 | #endif | ||
65 | #ifdef SYS_ioperm | ||
66 | filter_add_blacklist(fd, SYS_ioperm, 0); | ||
67 | #endif | ||
68 | #ifdef SYS_ioprio_set | ||
69 | filter_add_blacklist(fd, SYS_ioprio_set, 0); | ||
70 | #endif | ||
71 | #ifdef SYS_ni_syscall | ||
72 | filter_add_blacklist(fd, SYS_ni_syscall, 0); | ||
73 | #endif | ||
74 | #ifdef SYS_swapon | ||
75 | filter_add_blacklist(fd, SYS_swapon, 0); | ||
76 | #endif | ||
77 | #ifdef SYS_swapoff | ||
78 | filter_add_blacklist(fd, SYS_swapoff, 0); | ||
79 | #endif | ||
80 | #ifdef SYS_syslog | ||
81 | filter_add_blacklist(fd, SYS_syslog, 0); | ||
82 | #endif | ||
83 | |||
84 | if (!allow_debuggers) { | ||
85 | #ifdef SYS_process_vm_readv | ||
86 | filter_add_blacklist(fd, SYS_process_vm_readv, 0); | ||
87 | #endif | ||
88 | } | ||
89 | |||
90 | #ifdef SYS_process_vm_writev | ||
91 | filter_add_blacklist(fd, SYS_process_vm_writev, 0); | ||
92 | #endif | ||
93 | |||
94 | // mknod removed in 0.9.29 - it brakes Zotero extension | ||
95 | //#ifdef SYS_mknod | ||
96 | // filter_add_blacklist(SYS_mknod, 0); | ||
97 | //#endif | ||
98 | |||
99 | #ifdef SYS_sysfs | ||
100 | filter_add_blacklist(fd, SYS_sysfs, 0); | ||
101 | #endif | ||
102 | #ifdef SYS__sysctl | ||
103 | filter_add_blacklist(fd, SYS__sysctl, 0); | ||
104 | #endif | ||
105 | #ifdef SYS_adjtimex | ||
106 | filter_add_blacklist(fd, SYS_adjtimex, 0); | ||
107 | #endif | ||
108 | #ifdef SYS_clock_adjtime | ||
109 | filter_add_blacklist(fd, SYS_clock_adjtime, 0); | ||
110 | #endif | ||
111 | #ifdef SYS_lookup_dcookie | ||
112 | filter_add_blacklist(fd, SYS_lookup_dcookie, 0); | ||
113 | #endif | ||
114 | #ifdef SYS_perf_event_open | ||
115 | filter_add_blacklist(fd, SYS_perf_event_open, 0); | ||
116 | #endif | ||
117 | #ifdef SYS_fanotify_init | ||
118 | filter_add_blacklist(fd, SYS_fanotify_init, 0); | ||
119 | #endif | ||
120 | #ifdef SYS_kcmp | ||
121 | filter_add_blacklist(fd, SYS_kcmp, 0); | ||
122 | #endif | ||
123 | #ifdef SYS_add_key | ||
124 | filter_add_blacklist(fd, SYS_add_key, 0); | ||
125 | #endif | ||
126 | #ifdef SYS_request_key | ||
127 | filter_add_blacklist(fd, SYS_request_key, 0); | ||
128 | #endif | ||
129 | #ifdef SYS_keyctl | ||
130 | filter_add_blacklist(fd, SYS_keyctl, 0); | ||
131 | #endif | ||
132 | #ifdef SYS_uselib | ||
133 | filter_add_blacklist(fd, SYS_uselib, 0); | ||
134 | #endif | ||
135 | #ifdef SYS_acct | ||
136 | filter_add_blacklist(fd, SYS_acct, 0); | ||
137 | #endif | ||
138 | #ifdef SYS_modify_ldt | ||
139 | filter_add_blacklist(fd, SYS_modify_ldt, 0); | ||
140 | #endif | ||
141 | #ifdef SYS_pivot_root | ||
142 | filter_add_blacklist(fd, SYS_pivot_root, 0); | ||
143 | #endif | ||
144 | #ifdef SYS_io_setup | ||
145 | filter_add_blacklist(fd, SYS_io_setup, 0); | ||
146 | #endif | ||
147 | #ifdef SYS_io_destroy | ||
148 | filter_add_blacklist(fd, SYS_io_destroy, 0); | ||
149 | #endif | ||
150 | #ifdef SYS_io_getevents | ||
151 | filter_add_blacklist(fd, SYS_io_getevents, 0); | ||
152 | #endif | ||
153 | #ifdef SYS_io_submit | ||
154 | filter_add_blacklist(fd, SYS_io_submit, 0); | ||
155 | #endif | ||
156 | #ifdef SYS_io_cancel | ||
157 | filter_add_blacklist(fd, SYS_io_cancel, 0); | ||
158 | #endif | ||
159 | #ifdef SYS_remap_file_pages | ||
160 | filter_add_blacklist(fd, SYS_remap_file_pages, 0); | ||
161 | #endif | ||
162 | #ifdef SYS_mbind | ||
163 | filter_add_blacklist(fd, SYS_mbind, 0); | ||
164 | #endif | ||
165 | #ifdef SYS_get_mempolicy | ||
166 | filter_add_blacklist(fd, SYS_get_mempolicy, 0); | ||
167 | #endif | ||
168 | #ifdef SYS_set_mempolicy | ||
169 | filter_add_blacklist(fd, SYS_set_mempolicy, 0); | ||
170 | #endif | ||
171 | #ifdef SYS_migrate_pages | ||
172 | filter_add_blacklist(fd, SYS_migrate_pages, 0); | ||
173 | #endif | ||
174 | #ifdef SYS_move_pages | ||
175 | filter_add_blacklist(fd, SYS_move_pages, 0); | ||
176 | #endif | ||
177 | #ifdef SYS_vmsplice | ||
178 | filter_add_blacklist(fd, SYS_vmsplice, 0); | ||
179 | #endif | ||
180 | #ifdef SYS_chroot | ||
181 | filter_add_blacklist(fd, SYS_chroot, 0); | ||
182 | #endif | ||
183 | #ifdef SYS_tuxcall | ||
184 | filter_add_blacklist(fd, SYS_tuxcall, 0); | ||
185 | #endif | ||
186 | #ifdef SYS_reboot | ||
187 | filter_add_blacklist(fd, SYS_reboot, 0); | ||
188 | #endif | ||
189 | #ifdef SYS_nfsservctl | ||
190 | filter_add_blacklist(fd, SYS_nfsservctl, 0); | ||
191 | #endif | ||
192 | #ifdef SYS_get_kernel_syms | ||
193 | filter_add_blacklist(fd, SYS_get_kernel_syms, 0); | ||
194 | #endif | ||
195 | } | ||
196 | |||
197 | // default list | ||
198 | void seccomp_default(const char *fname, int allow_debuggers) { | ||
199 | assert(fname); | ||
200 | |||
201 | // open file | ||
202 | int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
203 | if (fd < 0) { | ||
204 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | ||
205 | exit(1); | ||
206 | } | ||
207 | |||
208 | // build filter | ||
209 | filter_init(fd); | ||
210 | add_default_list(fd, allow_debuggers); | ||
211 | filter_end_blacklist(fd); | ||
212 | |||
213 | // close file | ||
214 | close(fd); | ||
215 | } | ||
216 | |||
217 | // drop list | ||
218 | void seccomp_drop(const char *fname, char *list, int allow_debuggers) { | ||
219 | assert(fname); | ||
220 | (void) allow_debuggers; // todo: to implemnet it | ||
221 | |||
222 | // open file | ||
223 | int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
224 | if (fd < 0) { | ||
225 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | ||
226 | exit(1); | ||
227 | } | ||
228 | |||
229 | // build filter | ||
230 | filter_init(fd); | ||
231 | if (syscall_check_list(list, filter_add_blacklist, fd, 0)) { | ||
232 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | ||
233 | exit(1); | ||
234 | } | ||
235 | filter_end_blacklist(fd); | ||
236 | |||
237 | // close file | ||
238 | close(fd); | ||
239 | } | ||
240 | |||
241 | // default+drop | ||
242 | void seccomp_default_drop(const char *fname, char *list, int allow_debuggers) { | ||
243 | assert(fname); | ||
244 | |||
245 | // open file | ||
246 | int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
247 | if (fd < 0) { | ||
248 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | ||
249 | exit(1); | ||
250 | } | ||
251 | |||
252 | // build filter | ||
253 | filter_init(fd); | ||
254 | add_default_list(fd, allow_debuggers); | ||
255 | if (syscall_check_list(list, filter_add_blacklist, fd, 0)) { | ||
256 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | ||
257 | exit(1); | ||
258 | } | ||
259 | filter_end_blacklist(fd); | ||
260 | |||
261 | // close file | ||
262 | close(fd); | ||
263 | } | ||
264 | |||
265 | void seccomp_keep(const char *fname, char *list) { | ||
266 | // open file | ||
267 | int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
268 | if (fd < 0) { | ||
269 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | ||
270 | exit(1); | ||
271 | } | ||
272 | |||
273 | // build filter | ||
274 | filter_init(fd); | ||
275 | // these 4 syscalls are used by firejail after the seccomp filter is initialized | ||
276 | filter_add_whitelist(fd, SYS_setuid, 0); | ||
277 | filter_add_whitelist(fd, SYS_setgid, 0); | ||
278 | filter_add_whitelist(fd, SYS_setgroups, 0); | ||
279 | filter_add_whitelist(fd, SYS_dup, 0); | ||
280 | filter_add_whitelist(fd, SYS_prctl, 0); | ||
281 | |||
282 | if (syscall_check_list(list, filter_add_whitelist, fd, 0)) { | ||
283 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | ||
284 | exit(1); | ||
285 | } | ||
286 | |||
287 | filter_end_whitelist(fd); | ||
288 | |||
289 | // close file | ||
290 | close(fd); | ||
291 | } | ||
292 | |||
diff --git a/src/fseccomp/seccomp_file.c b/src/fseccomp/seccomp_file.c new file mode 100644 index 000000000..10ef9dd31 --- /dev/null +++ b/src/fseccomp/seccomp_file.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "fseccomp.h" | ||
21 | #include "../include/seccomp.h" | ||
22 | #include <sys/syscall.h> | ||
23 | |||
24 | static void write_to_file(int fd, void *data, int size) { | ||
25 | assert(data); | ||
26 | assert(size); | ||
27 | |||
28 | int written = 0; | ||
29 | while (written < size) { | ||
30 | int rv = write(fd, (unsigned char *) data + written, size - written); | ||
31 | if (rv == -1) { | ||
32 | fprintf(stderr, "Error fseccomp: cannot write seccomp file\n"); | ||
33 | exit(1); | ||
34 | } | ||
35 | written += rv; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | void filter_init(int fd) { | ||
40 | #if defined(__x86_64__) | ||
41 | #define X32_SYSCALL_BIT 0x40000000 | ||
42 | struct sock_filter filter[] = { | ||
43 | VALIDATE_ARCHITECTURE, | ||
44 | EXAMINE_SYSCALL, | ||
45 | // handle X32 ABI | ||
46 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), | ||
47 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), | ||
48 | RETURN_ERRNO(EPERM) | ||
49 | }; | ||
50 | #else | ||
51 | struct sock_filter filter[] = { | ||
52 | VALIDATE_ARCHITECTURE, | ||
53 | EXAMINE_SYSCALL | ||
54 | }; | ||
55 | #endif | ||
56 | |||
57 | #if 0 | ||
58 | { | ||
59 | int i; | ||
60 | unsigned char *ptr = (unsigned char *) &filter[0]; | ||
61 | for (i = 0; i < sizeof(filter); i++, ptr++) | ||
62 | printf("%x, ", (*ptr) & 0xff); | ||
63 | printf("\n"); | ||
64 | } | ||
65 | #endif | ||
66 | |||
67 | write_to_file(fd, filter, sizeof(filter)); | ||
68 | } | ||
69 | |||
70 | void filter_add_whitelist(int fd, int syscall, int arg) { | ||
71 | (void) arg; | ||
72 | |||
73 | struct sock_filter filter[] = { | ||
74 | WHITELIST(syscall) | ||
75 | }; | ||
76 | write_to_file(fd, filter, sizeof(filter)); | ||
77 | } | ||
78 | |||
79 | void filter_add_blacklist(int fd, int syscall, int arg) { | ||
80 | (void) arg; | ||
81 | |||
82 | struct sock_filter filter[] = { | ||
83 | BLACKLIST(syscall) | ||
84 | }; | ||
85 | write_to_file(fd, filter, sizeof(filter)); | ||
86 | } | ||
87 | |||
88 | void filter_add_errno(int fd, int syscall, int arg) { | ||
89 | struct sock_filter filter[] = { | ||
90 | BLACKLIST_ERRNO(syscall, arg) | ||
91 | }; | ||
92 | write_to_file(fd, filter, sizeof(filter)); | ||
93 | } | ||
94 | |||
95 | void filter_end_blacklist(int fd) { | ||
96 | struct sock_filter filter[] = { | ||
97 | RETURN_ALLOW | ||
98 | }; | ||
99 | write_to_file(fd, filter, sizeof(filter)); | ||
100 | } | ||
101 | |||
102 | void filter_end_whitelist(int fd) { | ||
103 | struct sock_filter filter[] = { | ||
104 | KILL_PROCESS | ||
105 | }; | ||
106 | write_to_file(fd, filter, sizeof(filter)); | ||
107 | } | ||
108 | |||
diff --git a/src/fseccomp/seccomp_print.c b/src/fseccomp/seccomp_print.c new file mode 100644 index 000000000..7dc983b12 --- /dev/null +++ b/src/fseccomp/seccomp_print.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "fseccomp.h" | ||
21 | #include "../include/seccomp.h" | ||
22 | #include <sys/syscall.h> | ||
23 | |||
24 | static struct sock_filter *filter = NULL; | ||
25 | static int filter_cnt = 0; | ||
26 | |||
27 | static void load_seccomp(const char *fname) { | ||
28 | assert(fname); | ||
29 | |||
30 | // check file | ||
31 | struct stat s; | ||
32 | if (stat(fname, &s) == -1) { | ||
33 | fprintf(stderr, "Error fseccomp: cannot read protocol filter file\n"); | ||
34 | exit(1); | ||
35 | } | ||
36 | int size = s.st_size; | ||
37 | unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter); | ||
38 | filter_cnt = entries; | ||
39 | //printf("size %d, entries %d\n", s.st_size, entries); | ||
40 | |||
41 | filter = malloc(sizeof(struct sock_filter) * entries); | ||
42 | if (!filter) | ||
43 | errExit("malloc"); | ||
44 | |||
45 | // read filter | ||
46 | memset(filter, 0, sizeof(struct sock_filter) * entries); | ||
47 | int src = open(fname, O_RDONLY); | ||
48 | int rd = 0; | ||
49 | while (rd < size) { | ||
50 | int rv = read(src, (unsigned char *) filter + rd, size - rd); | ||
51 | if (rv == -1) { | ||
52 | fprintf(stderr, "Error fseccomp: cannot read %s file\n", fname); | ||
53 | exit(1); | ||
54 | } | ||
55 | rd += rv; | ||
56 | } | ||
57 | close(src); | ||
58 | } | ||
59 | |||
60 | // debug filter | ||
61 | void filter_print(const char *fname) { | ||
62 | assert(fname); | ||
63 | load_seccomp(fname); | ||
64 | |||
65 | // start filter | ||
66 | struct sock_filter start[] = { | ||
67 | VALIDATE_ARCHITECTURE, | ||
68 | EXAMINE_SYSCALL | ||
69 | }; | ||
70 | |||
71 | // print sizes | ||
72 | printf("SECCOMP Filter:\n"); | ||
73 | |||
74 | // test the start of the filter | ||
75 | if (memcmp(&start[0], filter, sizeof(start)) == 0) { | ||
76 | printf(" VALIDATE_ARCHITECTURE\n"); | ||
77 | printf(" EXAMINE_SYSCAL\n"); | ||
78 | } | ||
79 | else { | ||
80 | printf("Invalid seccomp filter %s\n", fname); | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | // loop trough blacklists | ||
85 | int i = 4; | ||
86 | while (i < filter_cnt) { | ||
87 | // minimal parsing! | ||
88 | unsigned char *ptr = (unsigned char *) &filter[i]; | ||
89 | int *nr = (int *) (ptr + 4); | ||
90 | if (*ptr == 0x15 && *(ptr +14) == 0xff && *(ptr + 15) == 0x7f ) { | ||
91 | printf(" WHITELIST %d %s\n", *nr, syscall_find_nr(*nr)); | ||
92 | i += 2; | ||
93 | } | ||
94 | else if (*ptr == 0x15 && *(ptr +14) == 0 && *(ptr + 15) == 0) { | ||
95 | printf(" BLACKLIST %d %s\n", *nr, syscall_find_nr(*nr)); | ||
96 | i += 2; | ||
97 | } | ||
98 | else if (*ptr == 0x15 && *(ptr +14) == 0x5 && *(ptr + 15) == 0) { | ||
99 | int err = *(ptr + 13) << 8 | *(ptr + 12); | ||
100 | printf(" ERRNO %d %s %d %s\n", *nr, syscall_find_nr(*nr), err, errno_find_nr(err)); | ||
101 | i += 2; | ||
102 | } | ||
103 | else if (*ptr == 0x06 && *(ptr +6) == 0 && *(ptr + 7) == 0 ) { | ||
104 | printf(" KILL_PROCESS\n"); | ||
105 | i++; | ||
106 | } | ||
107 | else if (*ptr == 0x06 && *(ptr +6) == 0xff && *(ptr + 7) == 0x7f ) { | ||
108 | printf(" RETURN_ALLOW\n"); | ||
109 | i++; | ||
110 | } | ||
111 | else { | ||
112 | printf(" UNKNOWN ENTRY!!!\n"); | ||
113 | i++; | ||
114 | } | ||
115 | } | ||
116 | } | ||
diff --git a/src/fseccomp/seccomp_secondary.c b/src/fseccomp/seccomp_secondary.c new file mode 100644 index 000000000..a856e5aef --- /dev/null +++ b/src/fseccomp/seccomp_secondary.c | |||
@@ -0,0 +1,183 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "fseccomp.h" | ||
21 | #include "../include/seccomp.h" | ||
22 | #include <sys/syscall.h> | ||
23 | |||
24 | void seccomp_secondary_64(const char *fname) { | ||
25 | // hardcoded syscall values | ||
26 | struct sock_filter filter[] = { | ||
27 | VALIDATE_ARCHITECTURE_64, | ||
28 | EXAMINE_SYSCALL, | ||
29 | BLACKLIST(165), // mount | ||
30 | BLACKLIST(166), // umount2 | ||
31 | // todo: implement --allow-debuggers | ||
32 | BLACKLIST(101), // ptrace | ||
33 | BLACKLIST(246), // kexec_load | ||
34 | BLACKLIST(304), // open_by_handle_at | ||
35 | BLACKLIST(303), // name_to_handle_at | ||
36 | BLACKLIST(174), // create_module | ||
37 | BLACKLIST(175), // init_module | ||
38 | BLACKLIST(313), // finit_module | ||
39 | BLACKLIST(176), // delete_module | ||
40 | BLACKLIST(172), // iopl | ||
41 | BLACKLIST(173), // ioperm | ||
42 | BLACKLIST(251), // ioprio_set | ||
43 | BLACKLIST(167), // swapon | ||
44 | BLACKLIST(168), // swapoff | ||
45 | BLACKLIST(103), // syslog | ||
46 | BLACKLIST(310), // process_vm_readv | ||
47 | BLACKLIST(311), // process_vm_writev | ||
48 | BLACKLIST(139), // sysfs | ||
49 | BLACKLIST(156), // _sysctl | ||
50 | BLACKLIST(159), // adjtimex | ||
51 | BLACKLIST(305), // clock_adjtime | ||
52 | BLACKLIST(212), // lookup_dcookie | ||
53 | BLACKLIST(298), // perf_event_open | ||
54 | BLACKLIST(300), // fanotify_init | ||
55 | BLACKLIST(312), // kcmp | ||
56 | BLACKLIST(248), // add_key | ||
57 | BLACKLIST(249), // request_key | ||
58 | BLACKLIST(250), // keyctl | ||
59 | BLACKLIST(134), // uselib | ||
60 | BLACKLIST(163), // acct | ||
61 | BLACKLIST(154), // modify_ldt | ||
62 | BLACKLIST(155), // pivot_root | ||
63 | BLACKLIST(206), // io_setup | ||
64 | BLACKLIST(207), // io_destroy | ||
65 | BLACKLIST(208), // io_getevents | ||
66 | BLACKLIST(209), // io_submit | ||
67 | BLACKLIST(210), // io_cancel | ||
68 | BLACKLIST(216), // remap_file_pages | ||
69 | BLACKLIST(237), // mbind | ||
70 | BLACKLIST(239), // get_mempolicy | ||
71 | BLACKLIST(238), // set_mempolicy | ||
72 | BLACKLIST(256), // migrate_pages | ||
73 | BLACKLIST(279), // move_pages | ||
74 | BLACKLIST(278), // vmsplice | ||
75 | BLACKLIST(161), // chroot | ||
76 | BLACKLIST(184), // tuxcall | ||
77 | BLACKLIST(169), // reboot | ||
78 | BLACKLIST(180), // nfsservctl | ||
79 | BLACKLIST(177), // get_kernel_syms | ||
80 | |||
81 | RETURN_ALLOW | ||
82 | }; | ||
83 | |||
84 | // save filter to file | ||
85 | int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
86 | if (dst < 0) { | ||
87 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | ||
88 | exit(1); | ||
89 | } | ||
90 | |||
91 | int size = (int) sizeof(filter); | ||
92 | int written = 0; | ||
93 | while (written < size) { | ||
94 | int rv = write(dst, (unsigned char *) filter + written, size - written); | ||
95 | if (rv == -1) { | ||
96 | fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname); | ||
97 | exit(1); | ||
98 | } | ||
99 | written += rv; | ||
100 | } | ||
101 | close(dst); | ||
102 | } | ||
103 | |||
104 | // i386 filter installed on amd64 architectures | ||
105 | void seccomp_secondary_32(const char *fname) { | ||
106 | // hardcoded syscall values | ||
107 | struct sock_filter filter[] = { | ||
108 | VALIDATE_ARCHITECTURE_32, | ||
109 | EXAMINE_SYSCALL, | ||
110 | BLACKLIST(21), // mount | ||
111 | BLACKLIST(52), // umount2 | ||
112 | // todo: implement --allow-debuggers | ||
113 | BLACKLIST(26), // ptrace | ||
114 | BLACKLIST(283), // kexec_load | ||
115 | BLACKLIST(341), // name_to_handle_at | ||
116 | BLACKLIST(342), // open_by_handle_at | ||
117 | BLACKLIST(127), // create_module | ||
118 | BLACKLIST(128), // init_module | ||
119 | BLACKLIST(350), // finit_module | ||
120 | BLACKLIST(129), // delete_module | ||
121 | BLACKLIST(110), // iopl | ||
122 | BLACKLIST(101), // ioperm | ||
123 | BLACKLIST(289), // ioprio_set | ||
124 | BLACKLIST(87), // swapon | ||
125 | BLACKLIST(115), // swapoff | ||
126 | BLACKLIST(103), // syslog | ||
127 | BLACKLIST(347), // process_vm_readv | ||
128 | BLACKLIST(348), // process_vm_writev | ||
129 | BLACKLIST(135), // sysfs | ||
130 | BLACKLIST(149), // _sysctl | ||
131 | BLACKLIST(124), // adjtimex | ||
132 | BLACKLIST(343), // clock_adjtime | ||
133 | BLACKLIST(253), // lookup_dcookie | ||
134 | BLACKLIST(336), // perf_event_open | ||
135 | BLACKLIST(338), // fanotify_init | ||
136 | BLACKLIST(349), // kcmp | ||
137 | BLACKLIST(286), // add_key | ||
138 | BLACKLIST(287), // request_key | ||
139 | BLACKLIST(288), // keyctl | ||
140 | BLACKLIST(86), // uselib | ||
141 | BLACKLIST(51), // acct | ||
142 | BLACKLIST(123), // modify_ldt | ||
143 | BLACKLIST(217), // pivot_root | ||
144 | BLACKLIST(245), // io_setup | ||
145 | BLACKLIST(246), // io_destroy | ||
146 | BLACKLIST(247), // io_getevents | ||
147 | BLACKLIST(248), // io_submit | ||
148 | BLACKLIST(249), // io_cancel | ||
149 | BLACKLIST(257), // remap_file_pages | ||
150 | BLACKLIST(274), // mbind | ||
151 | BLACKLIST(275), // get_mempolicy | ||
152 | BLACKLIST(276), // set_mempolicy | ||
153 | BLACKLIST(294), // migrate_pages | ||
154 | BLACKLIST(317), // move_pages | ||
155 | BLACKLIST(316), // vmsplice | ||
156 | BLACKLIST(61), // chroot | ||
157 | BLACKLIST(88), // reboot | ||
158 | BLACKLIST(169), // nfsservctl | ||
159 | BLACKLIST(130), // get_kernel_syms | ||
160 | |||
161 | RETURN_ALLOW | ||
162 | }; | ||
163 | |||
164 | // save filter to file | ||
165 | int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
166 | if (dst < 0) { | ||
167 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | ||
168 | exit(1); | ||
169 | } | ||
170 | |||
171 | int size = (int) sizeof(filter); | ||
172 | int written = 0; | ||
173 | while (written < size) { | ||
174 | int rv = write(dst, (unsigned char *) filter + written, size - written); | ||
175 | if (rv == -1) { | ||
176 | fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname); | ||
177 | exit(1); | ||
178 | } | ||
179 | written += rv; | ||
180 | } | ||
181 | close(dst); | ||
182 | } | ||
183 | |||
diff --git a/src/fseccomp/syscall.c b/src/fseccomp/syscall.c index c67d45598..e2052efde 100644 --- a/src/fseccomp/syscall.c +++ b/src/fseccomp/syscall.c | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
1 | #include "fseccomp.h" | 20 | #include "fseccomp.h" |
2 | #include <sys/syscall.h> | 21 | #include <sys/syscall.h> |
3 | 22 | ||
@@ -16,6 +35,29 @@ static SyscallEntry syslist[] = { | |||
16 | // | 35 | // |
17 | }; // end of syslist | 36 | }; // end of syslist |
18 | 37 | ||
38 | // return -1 if error, or syscall number | ||
39 | int syscall_find_name(const char *name) { | ||
40 | int i; | ||
41 | int elems = sizeof(syslist) / sizeof(syslist[0]); | ||
42 | for (i = 0; i < elems; i++) { | ||
43 | if (strcmp(name, syslist[i].name) == 0) | ||
44 | return syslist[i].nr; | ||
45 | } | ||
46 | |||
47 | return -1; | ||
48 | } | ||
49 | |||
50 | char *syscall_find_nr(int nr) { | ||
51 | int i; | ||
52 | int elems = sizeof(syslist) / sizeof(syslist[0]); | ||
53 | for (i = 0; i < elems; i++) { | ||
54 | if (nr == syslist[i].nr) | ||
55 | return syslist[i].name; | ||
56 | } | ||
57 | |||
58 | return "unknown"; | ||
59 | } | ||
60 | |||
19 | void syscall_print(void) { | 61 | void syscall_print(void) { |
20 | int i; | 62 | int i; |
21 | int elems = sizeof(syslist) / sizeof(syslist[0]); | 63 | int elems = sizeof(syslist) / sizeof(syslist[0]); |
@@ -24,3 +66,45 @@ void syscall_print(void) { | |||
24 | } | 66 | } |
25 | printf("\n"); | 67 | printf("\n"); |
26 | } | 68 | } |
69 | |||
70 | // return 1 if error, 0 if OK | ||
71 | int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg) { | ||
72 | // don't allow empty lists | ||
73 | if (slist == NULL || *slist == '\0') { | ||
74 | fprintf(stderr, "Error: empty syscall lists are not allowed\n"); | ||
75 | return -1; | ||
76 | } | ||
77 | |||
78 | // work on a copy of the string | ||
79 | char *str = strdup(slist); | ||
80 | if (!str) | ||
81 | errExit("strdup"); | ||
82 | |||
83 | char *ptr = str; | ||
84 | char *start = str; | ||
85 | while (*ptr != '\0') { | ||
86 | if (islower(*ptr) || isdigit(*ptr) || *ptr == '_') | ||
87 | ; | ||
88 | else if (*ptr == ',') { | ||
89 | *ptr = '\0'; | ||
90 | int nr = syscall_find_name(start); | ||
91 | if (nr == -1) | ||
92 | fprintf(stderr, "Warning: syscall %s not found\n", start); | ||
93 | else if (callback != NULL) | ||
94 | callback(fd, nr, arg); | ||
95 | |||
96 | start = ptr + 1; | ||
97 | } | ||
98 | ptr++; | ||
99 | } | ||
100 | if (*start != '\0') { | ||
101 | int nr = syscall_find_name(start); | ||
102 | if (nr == -1) | ||
103 | fprintf(stderr, "Warning: syscall %s not found\n", start); | ||
104 | else if (callback != NULL) | ||
105 | callback(fd, nr, arg); | ||
106 | } | ||
107 | |||
108 | free(str); | ||
109 | return 0; | ||
110 | } | ||