aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/firejail/seccomp.c5
-rw-r--r--src/fseccomp/fseccomp.h2
-rw-r--r--src/fseccomp/seccomp.c12
-rw-r--r--src/fseccomp/seccomp_file.c48
-rw-r--r--src/fseccomp/syscall.c10
-rw-r--r--src/man/firejail.txt23
6 files changed, 80 insertions, 20 deletions
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 81ab18aa1..609ebb7be 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -48,10 +48,11 @@ char *seccomp_check_list(const char *str) {
48 const char *ptr1 = str; 48 const char *ptr1 = str;
49 char *ptr2 = rv; 49 char *ptr2 = rv;
50 while (*ptr1 != '\0') { 50 while (*ptr1 != '\0') {
51 if (isalnum(*ptr1) || *ptr1 == '_' || *ptr1 == ',' || *ptr1 == ':' || *ptr1 == '@' || *ptr1 == '-') 51 if (isalnum(*ptr1) || *ptr1 == '_' || *ptr1 == ',' || *ptr1 == ':'
52 || *ptr1 == '@' || *ptr1 == '-' || *ptr1 == '$' || *ptr1 == '!')
52 *ptr2++ = *ptr1++; 53 *ptr2++ = *ptr1++;
53 else { 54 else {
54 fprintf(stderr, "Error: invalid syscall list\n"); 55 fprintf(stderr, "Error: invalid syscall list entry %s\n", str);
55 exit(1); 56 exit(1);
56 } 57 }
57 } 58 }
diff --git a/src/fseccomp/fseccomp.h b/src/fseccomp/fseccomp.h
index 593963e76..e1579d098 100644
--- a/src/fseccomp/fseccomp.h
+++ b/src/fseccomp/fseccomp.h
@@ -52,7 +52,9 @@ void seccomp_secondary_block(const char *fname);
52void write_to_file(int fd, const void *data, int size); 52void write_to_file(int fd, const void *data, int size);
53void filter_init(int fd); 53void filter_init(int fd);
54void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg); 54void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg);
55void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg);
55void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg); 56void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg);
57void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg);
56void filter_add_errno(int fd, int syscall, int arg, void *ptrarg); 58void filter_add_errno(int fd, int syscall, int arg, void *ptrarg);
57void filter_end_blacklist(int fd); 59void filter_end_blacklist(int fd);
58void filter_end_whitelist(int fd); 60void filter_end_whitelist(int fd);
diff --git a/src/fseccomp/seccomp.c b/src/fseccomp/seccomp.c
index 2a719725e..95c20d388 100644
--- a/src/fseccomp/seccomp.c
+++ b/src/fseccomp/seccomp.c
@@ -80,6 +80,10 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
80 80
81 // build pre-exec filter: don't blacklist any syscalls in @default-keep 81 // build pre-exec filter: don't blacklist any syscalls in @default-keep
82 filter_init(fd); 82 filter_init(fd);
83
84 // allow exceptions in form of !syscall
85 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL);
86
83 char *prelist, *postlist; 87 char *prelist, *postlist;
84 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); 88 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist);
85 if (prelist) 89 if (prelist)
@@ -128,6 +132,10 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
128 // build pre-exec filter: blacklist @default, don't blacklist 132 // build pre-exec filter: blacklist @default, don't blacklist
129 // any listed syscalls in @default-keep 133 // any listed syscalls in @default-keep
130 filter_init(fd); 134 filter_init(fd);
135
136 // allow exceptions in form of !syscall
137 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL);
138
131 add_default_list(fd, allow_debuggers); 139 add_default_list(fd, allow_debuggers);
132 char *prelist, *postlist; 140 char *prelist, *postlist;
133 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); 141 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist);
@@ -175,6 +183,10 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
175 183
176 // build pre-exec filter: whitelist also @default-keep 184 // build pre-exec filter: whitelist also @default-keep
177 filter_init(fd); 185 filter_init(fd);
186
187 // allow exceptions in form of !syscall
188 syscall_check_list(list, filter_add_blacklist_for_excluded, fd, 0, NULL);
189
178 // these syscalls are used by firejail after the seccomp filter is initialized 190 // these syscalls are used by firejail after the seccomp filter is initialized
179 int r; 191 int r;
180 r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0, NULL); 192 r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0, NULL);
diff --git a/src/fseccomp/seccomp_file.c b/src/fseccomp/seccomp_file.c
index 2e1f317ed..266ef0c55 100644
--- a/src/fseccomp/seccomp_file.c
+++ b/src/fseccomp/seccomp_file.c
@@ -60,26 +60,58 @@ void filter_init(int fd) {
60 write_to_file(fd, filter, sizeof(filter)); 60 write_to_file(fd, filter, sizeof(filter));
61} 61}
62 62
63void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) { 63static void write_whitelist(int fd, int syscall) {
64 (void) arg;
65 (void) ptrarg;
66
67 struct sock_filter filter[] = { 64 struct sock_filter filter[] = {
68 WHITELIST(syscall) 65 WHITELIST(syscall)
69 }; 66 };
70 write_to_file(fd, filter, sizeof(filter)); 67 write_to_file(fd, filter, sizeof(filter));
71} 68}
72 69
73void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) { 70static void write_blacklist(int fd, int syscall) {
74 (void) arg;
75 (void) ptrarg;
76
77 struct sock_filter filter[] = { 71 struct sock_filter filter[] = {
78 BLACKLIST(syscall) 72 BLACKLIST(syscall)
79 }; 73 };
80 write_to_file(fd, filter, sizeof(filter)); 74 write_to_file(fd, filter, sizeof(filter));
81} 75}
82 76
77void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) {
78 (void) arg;
79 (void) ptrarg;
80
81 if (syscall >= 0) {
82 write_whitelist(fd, syscall);
83 }
84}
85
86// handle seccomp list exceptions (seccomp x,y,!z)
87void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg) {
88 (void) arg;
89 (void) ptrarg;
90
91 if (syscall < 0) {
92 write_whitelist(fd, -syscall);
93 }
94}
95
96void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) {
97 (void) arg;
98 (void) ptrarg;
99
100 if (syscall >= 0) {
101 write_blacklist(fd, syscall);
102 }
103}
104
105// handle seccomp list exceptions (seccomp x,y,!z)
106void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg) {
107 (void) arg;
108 (void) ptrarg;
109
110 if (syscall < 0) {
111 write_blacklist(fd, -syscall);
112 }
113}
114
83void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) { 115void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) {
84 (void) ptrarg; 116 (void) ptrarg;
85 struct sock_filter filter[] = { 117 struct sock_filter filter[] = {
diff --git a/src/fseccomp/syscall.c b/src/fseccomp/syscall.c
index 2acbdd989..5d83786bb 100644
--- a/src/fseccomp/syscall.c
+++ b/src/fseccomp/syscall.c
@@ -1485,9 +1485,17 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall,
1485 syscall_check_list(new_list, callback, fd, arg, ptrarg); 1485 syscall_check_list(new_list, callback, fd, arg, ptrarg);
1486 } 1486 }
1487 else { 1487 else {
1488 bool negate = false;
1489 if (*ptr == '!') {
1490 negate = true;
1491 ptr++;
1492 }
1488 syscall_process_name(ptr, &syscall_nr, &error_nr); 1493 syscall_process_name(ptr, &syscall_nr, &error_nr);
1489 if (syscall_nr == -1) {;} 1494 if (syscall_nr == -1) {;}
1490 else if (callback != NULL) { 1495 else if (callback != NULL) {
1496 if (negate) {
1497 syscall_nr = -syscall_nr;
1498 }
1491 if (error_nr != -1 && fd != 0) { 1499 if (error_nr != -1 && fd != 0) {
1492 filter_add_errno(fd, syscall_nr, error_nr, ptrarg); 1500 filter_add_errno(fd, syscall_nr, error_nr, ptrarg);
1493 } 1501 }
@@ -1510,7 +1518,7 @@ static void find_syscall(int fd, int syscall, int arg, void *ptrarg) {
1510 (void)fd; 1518 (void)fd;
1511 (void) arg; 1519 (void) arg;
1512 SyscallCheckList *ptr = ptrarg; 1520 SyscallCheckList *ptr = ptrarg;
1513 if (syscall == ptr->syscall) 1521 if (abs(syscall) == ptr->syscall)
1514 ptr->found = true; 1522 ptr->found = true;
1515} 1523}
1516 1524
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index b0c12ee11..500850413 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -1782,7 +1782,8 @@ system call groups are defined: @aio, @basic-io, @chown, @clock,
1782@network-io, @obsolete, @privileged, @process, @raw-io, @reboot, 1782@network-io, @obsolete, @privileged, @process, @raw-io, @reboot,
1783@resources, @setuid, @swap, @sync, @system-service and @timer. In addition, a 1783@resources, @setuid, @swap, @sync, @system-service and @timer. In addition, a
1784system call can be specified by its number instead of name with prefix 1784system call can be specified by its number instead of name with prefix
1785$, so for example $165 would be equal to mount on i386. 1785$, so for example $165 would be equal to mount on i386. Exceptions
1786can be allowed with prefix !.
1786 1787
1787.br 1788.br
1788System architecture is strictly imposed only if flag 1789System architecture is strictly imposed only if flag
@@ -1800,8 +1801,10 @@ Example:
1800.br 1801.br
1801$ firejail \-\-seccomp 1802$ firejail \-\-seccomp
1802.TP 1803.TP
1803\fB\-\-seccomp=syscall,@group 1804\fB\-\-seccomp=syscall,@group,!syscall2
1804Enable seccomp filter, blacklist the default list (@default) and the syscalls or syscall groups specified by the command. 1805Enable seccomp filter, whitelist "syscall2", but blacklist the default
1806list (@default) and the syscalls or syscall groups specified by the
1807command.
1805.br 1808.br
1806 1809
1807.br 1810.br
@@ -1865,8 +1868,9 @@ domain with personality(2) system call.
1865.br 1868.br
1866 1869
1867.TP 1870.TP
1868\fB\-\-seccomp.drop=syscall,@group 1871\fB\-\-seccomp.drop=syscall,@group,!syscall2
1869Enable seccomp filter, and blacklist the syscalls or the syscall groups specified by the command. 1872Enable seccomp filter, whitelist "syscall2" but blacklist the
1873syscalls or the syscall groups specified by the command.
1870.br 1874.br
1871 1875
1872.br 1876.br
@@ -1901,10 +1905,11 @@ rm: cannot remove `testfile': Operation not permitted
1901 1905
1902 1906
1903.TP 1907.TP
1904\fB\-\-seccomp.keep=syscall,syscall,syscall 1908\fB\-\-seccomp.keep=syscall,@group,!syscall2
1905Enable seccomp filter, and whitelist the syscalls specified by the 1909Enable seccomp filter, blacklist "syscall2" but whitelist the
1906command. The system calls needed by Firejail (group @default-keep: 1910syscalls or the syscall groups specified by the command. The system
1907prctl, execve) are handled with the preload library. 1911calls needed by Firejail (group @default-keep: prctl, execve) are
1912handled with the preload library.
1908.br 1913.br
1909 1914
1910.br 1915.br