diff options
author | Topi Miettinen <toiwoton@gmail.com> | 2020-03-14 00:07:06 +0200 |
---|---|---|
committer | Topi Miettinen <topimiettinen@users.noreply.github.com> | 2020-03-28 11:24:25 +0000 |
commit | 88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3 (patch) | |
tree | 6b4d2a805a2900755bfc857586a10948b3c8395e /src/fseccomp/seccomp_file.c | |
parent | Added compatibility with BetterDiscord (#3300) (diff) | |
download | firejail-88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3.tar.gz firejail-88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3.tar.zst firejail-88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3.zip |
seccomp: allow defining separate filters for 32-bit arch
System calls (names and numbers) are not exactly the same for 32 bit
and 64 bit architectures. Let's allow defining separate filters for
32-bit arch using seccomp.32, seccomp.32.drop, seccomp.32.keep. This
is useful for mixed 64/32 bit application environments like Steam and
Wine.
Implement protocol and mdwx filtering also for 32 bit arch. It's still
better to block secondary archs completely if not needed.
Lists of supported system calls are also updated.
Warn if preload libraries would be needed due to trace, tracelog or
postexecseccomp (seccomp.drop=execve etc), because a 32-bit dynamic
linker does not understand the 64 bit preload libraries.
Closes #3267.
Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
Diffstat (limited to 'src/fseccomp/seccomp_file.c')
-rw-r--r-- | src/fseccomp/seccomp_file.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/src/fseccomp/seccomp_file.c b/src/fseccomp/seccomp_file.c index e47e8db25..872b41261 100644 --- a/src/fseccomp/seccomp_file.c +++ b/src/fseccomp/seccomp_file.c | |||
@@ -21,11 +21,11 @@ | |||
21 | #include "../include/seccomp.h" | 21 | #include "../include/seccomp.h" |
22 | #include <sys/syscall.h> | 22 | #include <sys/syscall.h> |
23 | 23 | ||
24 | void write_to_file(int fd, const void *data, int size) { | 24 | void write_to_file(int fd, const void *data, size_t size) { |
25 | assert(data); | 25 | assert(data); |
26 | assert(size); | 26 | assert(size); |
27 | 27 | ||
28 | int written = 0; | 28 | size_t written = 0; |
29 | while (written < size) { | 29 | while (written < size) { |
30 | int rv = write(fd, (unsigned char *) data + written, size - written); | 30 | int rv = write(fd, (unsigned char *) data + written, size - written); |
31 | if (rv == -1) { | 31 | if (rv == -1) { |
@@ -36,8 +36,8 @@ void write_to_file(int fd, const void *data, int size) { | |||
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | void filter_init(int fd) { | 39 | void filter_init(int fd, bool native) { |
40 | struct sock_filter filter[] = { | 40 | struct sock_filter filter_native[] = { |
41 | VALIDATE_ARCHITECTURE, | 41 | VALIDATE_ARCHITECTURE, |
42 | #if defined(__x86_64__) | 42 | #if defined(__x86_64__) |
43 | EXAMINE_SYSCALL, | 43 | EXAMINE_SYSCALL, |
@@ -46,6 +46,10 @@ void filter_init(int fd) { | |||
46 | EXAMINE_SYSCALL | 46 | EXAMINE_SYSCALL |
47 | #endif | 47 | #endif |
48 | }; | 48 | }; |
49 | struct sock_filter filter_32[] = { | ||
50 | VALIDATE_ARCHITECTURE_32, | ||
51 | EXAMINE_SYSCALL | ||
52 | }; | ||
49 | 53 | ||
50 | #if 0 | 54 | #if 0 |
51 | { | 55 | { |
@@ -57,7 +61,10 @@ void filter_init(int fd) { | |||
57 | } | 61 | } |
58 | #endif | 62 | #endif |
59 | 63 | ||
60 | write_to_file(fd, filter, sizeof(filter)); | 64 | if (native) |
65 | write_to_file(fd, filter_native, sizeof(filter_native)); | ||
66 | else | ||
67 | write_to_file(fd, filter_32, sizeof(filter_32)); | ||
61 | } | 68 | } |
62 | 69 | ||
63 | static void write_whitelist(int fd, int syscall) { | 70 | static void write_whitelist(int fd, int syscall) { |
@@ -74,9 +81,10 @@ static void write_blacklist(int fd, int syscall) { | |||
74 | write_to_file(fd, filter, sizeof(filter)); | 81 | write_to_file(fd, filter, sizeof(filter)); |
75 | } | 82 | } |
76 | 83 | ||
77 | void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) { | 84 | void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg, bool native) { |
78 | (void) arg; | 85 | (void) arg; |
79 | (void) ptrarg; | 86 | (void) ptrarg; |
87 | (void) native; | ||
80 | 88 | ||
81 | if (syscall >= 0) { | 89 | if (syscall >= 0) { |
82 | write_whitelist(fd, syscall); | 90 | write_whitelist(fd, syscall); |
@@ -84,18 +92,20 @@ void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) { | |||
84 | } | 92 | } |
85 | 93 | ||
86 | // handle seccomp list exceptions (seccomp x,y,!z) | 94 | // handle seccomp list exceptions (seccomp x,y,!z) |
87 | void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg) { | 95 | void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native) { |
88 | (void) arg; | 96 | (void) arg; |
89 | (void) ptrarg; | 97 | (void) ptrarg; |
98 | (void) native; | ||
90 | 99 | ||
91 | if (syscall < 0) { | 100 | if (syscall < 0) { |
92 | write_whitelist(fd, -syscall); | 101 | write_whitelist(fd, -syscall); |
93 | } | 102 | } |
94 | } | 103 | } |
95 | 104 | ||
96 | void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) { | 105 | void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg, bool native) { |
97 | (void) arg; | 106 | (void) arg; |
98 | (void) ptrarg; | 107 | (void) ptrarg; |
108 | (void) native; | ||
99 | 109 | ||
100 | if (syscall >= 0) { | 110 | if (syscall >= 0) { |
101 | write_blacklist(fd, syscall); | 111 | write_blacklist(fd, syscall); |
@@ -103,17 +113,20 @@ void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) { | |||
103 | } | 113 | } |
104 | 114 | ||
105 | // handle seccomp list exceptions (seccomp x,y,!z) | 115 | // handle seccomp list exceptions (seccomp x,y,!z) |
106 | void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg) { | 116 | void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native) { |
107 | (void) arg; | 117 | (void) arg; |
108 | (void) ptrarg; | 118 | (void) ptrarg; |
119 | (void) native; | ||
109 | 120 | ||
110 | if (syscall < 0) { | 121 | if (syscall < 0) { |
111 | write_blacklist(fd, -syscall); | 122 | write_blacklist(fd, -syscall); |
112 | } | 123 | } |
113 | } | 124 | } |
114 | 125 | ||
115 | void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) { | 126 | void filter_add_errno(int fd, int syscall, int arg, void *ptrarg, bool native) { |
116 | (void) ptrarg; | 127 | (void) ptrarg; |
128 | (void) native; | ||
129 | |||
117 | struct sock_filter filter[] = { | 130 | struct sock_filter filter[] = { |
118 | BLACKLIST_ERRNO(syscall, arg) | 131 | BLACKLIST_ERRNO(syscall, arg) |
119 | }; | 132 | }; |