aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2021-01-31 00:15:31 +0200
committerLibravatar Topi Miettinen <topimiettinen@users.noreply.github.com>2021-02-01 20:09:21 +0000
commit0040969e439dbddb76bc190900b453b71e895068 (patch)
tree3d9606b116e47f8702d86fde5194d8c8d22fdde5 /src
parentAdd profile for avidemux (#3935) (diff)
downloadfirejail-0040969e439dbddb76bc190900b453b71e895068.tar.gz
firejail-0040969e439dbddb76bc190900b453b71e895068.tar.zst
firejail-0040969e439dbddb76bc190900b453b71e895068.zip
Seccomp error action fixes
fsec-optimize: Optimize BPF with current seccomp error action, not just KILL fseccomp: use correct BPF code for errno action firejail: honor seccomp error action for X32 and secondary filters, rebuild filters if the error action is changed Closes: #3933 Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/firejail/sbox.c2
-rw-r--r--src/firejail/seccomp.c46
-rw-r--r--src/fsec-optimize/Makefile.in2
-rw-r--r--src/fsec-optimize/main.c17
-rw-r--r--src/fsec-optimize/optimizer.c6
-rw-r--r--src/fseccomp/main.c2
-rw-r--r--src/fseccomp/seccomp_secondary.c2
-rw-r--r--src/include/seccomp.h10
8 files changed, 63 insertions, 24 deletions
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c
index a2aaa86eb..c3d3bd72c 100644
--- a/src/firejail/sbox.c
+++ b/src/firejail/sbox.c
@@ -120,7 +120,7 @@ static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char *
120 // handle X32 ABI 120 // handle X32 ABI
121 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, X32_SYSCALL_BIT, 1, 0), 121 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, X32_SYSCALL_BIT, 1, 0),
122 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, 0, 1, 0), 122 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, 0, 1, 0),
123 RETURN_ERRNO(EPERM), 123 KILL_OR_RETURN_ERRNO,
124#endif 124#endif
125 125
126 // syscall list 126 // syscall list
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index e47e6c910..808dd4c37 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -208,7 +208,7 @@ int seccomp_filter_drop(bool native) {
208 // - seccomp 208 // - seccomp
209 if (cfg.seccomp_list_drop == NULL) { 209 if (cfg.seccomp_list_drop == NULL) {
210 // default seccomp if error action is not changed 210 // default seccomp if error action is not changed
211 if (cfg.seccomp_list == NULL && cfg.seccomp_error_action) { 211 if (cfg.seccomp_list == NULL && arg_seccomp_error_action == DEFAULT_SECCOMP_ERROR_ACTION) {
212 if (arg_seccomp_block_secondary) 212 if (arg_seccomp_block_secondary)
213 seccomp_filter_block_secondary(); 213 seccomp_filter_block_secondary();
214 else { 214 else {
@@ -221,11 +221,29 @@ int seccomp_filter_drop(bool native) {
221 } 221 }
222 // default seccomp filter with additional drop list 222 // default seccomp filter with additional drop list
223 else { // cfg.seccomp_list != NULL 223 else { // cfg.seccomp_list != NULL
224 if (arg_seccomp_block_secondary) 224 int rv;
225
226 if (arg_seccomp_block_secondary) {
227 if (arg_seccomp_error_action != DEFAULT_SECCOMP_ERROR_ACTION) {
228 if (arg_debug)
229 printf("Rebuild secondary block seccomp filter\n");
230 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
231 PATH_FSECCOMP, "secondary", "block", RUN_SECCOMP_BLOCK_SECONDARY);
232 if (rv)
233 exit(rv);
234 }
225 seccomp_filter_block_secondary(); 235 seccomp_filter_block_secondary();
226 else { 236 } else {
227#if defined(__x86_64__) 237#if defined(__x86_64__)
228#if defined(__LP64__) 238#if defined(__LP64__)
239 if (arg_seccomp_error_action != DEFAULT_SECCOMP_ERROR_ACTION) {
240 if (arg_debug)
241 printf("Rebuild 32 bit seccomp filter\n");
242 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
243 PATH_FSECCOMP, "secondary", "32", RUN_SECCOMP_32);
244 if (rv)
245 exit(rv);
246 }
229 seccomp_filter_32(); 247 seccomp_filter_32();
230#endif 248#endif
231#endif 249#endif
@@ -242,16 +260,22 @@ int seccomp_filter_drop(bool native) {
242 list = cfg.seccomp_list32; 260 list = cfg.seccomp_list32;
243 } 261 }
244 262
245 if (list == NULL)
246 list = "";
247 // build the seccomp filter as a regular user 263 // build the seccomp filter as a regular user
248 int rv; 264 if (list)
249 if (arg_allow_debuggers) 265 if (arg_allow_debuggers)
250 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 7, 266 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 7,
251 PATH_FSECCOMP, command, "drop", filter, postexec_filter, list, "allow-debuggers"); 267 PATH_FSECCOMP, command, "drop", filter, postexec_filter, list, "allow-debuggers");
268 else
269 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6,
270 PATH_FSECCOMP, command, "drop", filter, postexec_filter, list);
252 else 271 else
253 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6, 272 if (arg_allow_debuggers)
254 PATH_FSECCOMP, command, "drop", filter, postexec_filter, list); 273 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
274 PATH_FSECCOMP, command, filter, "allow-debuggers");
275 else
276 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3,
277 PATH_FSECCOMP, command, filter);
278
255 if (rv) 279 if (rv)
256 exit(rv); 280 exit(rv);
257 281
diff --git a/src/fsec-optimize/Makefile.in b/src/fsec-optimize/Makefile.in
index b6a28fdd8..cc5ac7e35 100644
--- a/src/fsec-optimize/Makefile.in
+++ b/src/fsec-optimize/Makefile.in
@@ -6,7 +6,7 @@ include ../common.mk
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fsec-optimize: $(OBJS) ../lib/common.o ../lib/libnetlink.o 8fsec-optimize: $(OBJS) ../lib/common.o ../lib/libnetlink.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/errno.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fsec-optimize *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fsec-optimize *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fsec-optimize/main.c b/src/fsec-optimize/main.c
index 74aebc9e0..c64587068 100644
--- a/src/fsec-optimize/main.c
+++ b/src/fsec-optimize/main.c
@@ -18,6 +18,9 @@
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#include "fsec_optimize.h" 20#include "fsec_optimize.h"
21#include "../include/syscall.h"
22
23int arg_seccomp_error_action = SECCOMP_RET_ERRNO | EPERM; // error action: errno, log or kill
21 24
22static void usage(void) { 25static void usage(void) {
23 printf("Usage:\n"); 26 printf("Usage:\n");
@@ -46,6 +49,20 @@ printf("\n");
46 49
47 warn_dumpable(); 50 warn_dumpable();
48 51
52 char *error_action = getenv("FIREJAIL_SECCOMP_ERROR_ACTION");
53 if (error_action) {
54 if (strcmp(error_action, "kill") == 0)
55 arg_seccomp_error_action = SECCOMP_RET_KILL;
56 else if (strcmp(error_action, "log") == 0)
57 arg_seccomp_error_action = SECCOMP_RET_LOG;
58 else {
59 arg_seccomp_error_action = errno_find_name(error_action);
60 if (arg_seccomp_error_action == -1)
61 errExit("seccomp-error-action: unknown errno");
62 arg_seccomp_error_action |= SECCOMP_RET_ERRNO;
63 }
64 }
65
49 char *fname = argv[1]; 66 char *fname = argv[1];
50 67
51 // open input file 68 // open input file
diff --git a/src/fsec-optimize/optimizer.c b/src/fsec-optimize/optimizer.c
index 776beaa75..eb777f13b 100644
--- a/src/fsec-optimize/optimizer.c
+++ b/src/fsec-optimize/optimizer.c
@@ -33,7 +33,7 @@
33static inline int is_blacklist(struct sock_filter *bpf) { 33static inline int is_blacklist(struct sock_filter *bpf) {
34 if (bpf->code == BPF_JMP + BPF_JEQ + BPF_K && 34 if (bpf->code == BPF_JMP + BPF_JEQ + BPF_K &&
35 (bpf + 1)->code == BPF_RET + BPF_K && 35 (bpf + 1)->code == BPF_RET + BPF_K &&
36 (bpf + 1)->k == SECCOMP_RET_KILL ) 36 (bpf + 1)->k == (__u32)arg_seccomp_error_action)
37 return 1; 37 return 1;
38 return 0; 38 return 0;
39} 39}
@@ -89,9 +89,9 @@ static int optimize_blacklists(struct sock_filter *filter, int entries) {
89 } 89 }
90 } 90 }
91 91
92 // step 3: add the new ret KILL, and recalculate entries 92 // step 3: add the new ret KILL/LOG/ERRNO, and recalculate entries
93 filter_step2[j].code = BPF_RET + BPF_K; 93 filter_step2[j].code = BPF_RET + BPF_K;
94 filter_step2[j].k = SECCOMP_RET_KILL; 94 filter_step2[j].k = arg_seccomp_error_action;
95 entries = j + 1; 95 entries = j + 1;
96 96
97 // step 4: recalculate jumps 97 // step 4: recalculate jumps
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c
index c8259b079..f47efb5e8 100644
--- a/src/fseccomp/main.c
+++ b/src/fseccomp/main.c
@@ -20,7 +20,7 @@
20#include "fseccomp.h" 20#include "fseccomp.h"
21#include "../include/seccomp.h" 21#include "../include/seccomp.h"
22int arg_quiet = 0; 22int arg_quiet = 0;
23int arg_seccomp_error_action = EPERM; // error action: errno, log or kill 23int arg_seccomp_error_action = SECCOMP_RET_ERRNO | EPERM; // error action: errno, log or kill
24 24
25static void usage(void) { 25static void usage(void) {
26 printf("Usage:\n"); 26 printf("Usage:\n");
diff --git a/src/fseccomp/seccomp_secondary.c b/src/fseccomp/seccomp_secondary.c
index f024859d3..b8e8d0a89 100644
--- a/src/fseccomp/seccomp_secondary.c
+++ b/src/fseccomp/seccomp_secondary.c
@@ -126,7 +126,7 @@ void seccomp_secondary_block(const char *fname) {
126 EXAMINE_SYSCALL, 126 EXAMINE_SYSCALL,
127#if defined(__x86_64__) 127#if defined(__x86_64__)
128 // block x32 128 // block x32
129 HANDLE_X32_KILL, 129 HANDLE_X32,
130#endif 130#endif
131 // block personality(2) where domain != PER_LINUX or 0xffffffff (query current personality) 131 // block personality(2) where domain != PER_LINUX or 0xffffffff (query current personality)
132 // 0: if personality(2), continue to 1, else goto 7 (allow) 132 // 0: if personality(2), continue to 1, else goto 7 (allow)
diff --git a/src/include/seccomp.h b/src/include/seccomp.h
index 90db16d39..b3b75c2d1 100644
--- a/src/include/seccomp.h
+++ b/src/include/seccomp.h
@@ -201,7 +201,7 @@
201#define VALIDATE_ARCHITECTURE_KILL \ 201#define VALIDATE_ARCHITECTURE_KILL \
202 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ 202 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \
203 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ 203 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \
204 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) 204 KILL_OR_RETURN_ERRNO
205 205
206#define VALIDATE_ARCHITECTURE_64 \ 206#define VALIDATE_ARCHITECTURE_64 \
207 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ 207 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \
@@ -222,11 +222,7 @@
222#define HANDLE_X32 \ 222#define HANDLE_X32 \
223 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \ 223 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \
224 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \ 224 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \
225 RETURN_ERRNO(EPERM) 225 KILL_OR_RETURN_ERRNO
226#define HANDLE_X32_KILL \
227 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \
228 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \
229 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
230#endif 226#endif
231 227
232#define EXAMINE_SYSCALL BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 228#define EXAMINE_SYSCALL BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
@@ -258,6 +254,8 @@
258 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr) 254 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr)
259 255
260extern int arg_seccomp_error_action; // error action: errno, log or kill 256extern int arg_seccomp_error_action; // error action: errno, log or kill
257#define DEFAULT_SECCOMP_ERROR_ACTION EPERM
258
261#define KILL_OR_RETURN_ERRNO \ 259#define KILL_OR_RETURN_ERRNO \
262 BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action) 260 BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action)
263 261