diff options
author | netblue30 <netblue30@yahoo.com> | 2015-10-16 13:30:50 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2015-10-16 13:30:50 -0400 |
commit | 1eaa68fb0c03113ba01d8696f7c8c6ddbffa8488 (patch) | |
tree | b7fa247213e094e1be224597e8f53edaac685ccd | |
parent | fix 32bit compilation (diff) | |
download | firejail-1eaa68fb0c03113ba01d8696f7c8c6ddbffa8488.tar.gz firejail-1eaa68fb0c03113ba01d8696f7c8c6ddbffa8488.tar.zst firejail-1eaa68fb0c03113ba01d8696f7c8c6ddbffa8488.zip |
debian 32bit fixes
-rw-r--r-- | src/firejail/fs_dev.c | 53 | ||||
-rwxr-xr-x | test/option-trace.exp | 5 | ||||
-rwxr-xr-x | test/seccomp-errno.exp | 2 | ||||
-rw-r--r-- | todo | 120 |
4 files changed, 38 insertions, 142 deletions
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c index 7560d5fef..881f20b1f 100644 --- a/src/firejail/fs_dev.c +++ b/src/firejail/fs_dev.c | |||
@@ -62,38 +62,49 @@ errexit: | |||
62 | } | 62 | } |
63 | 63 | ||
64 | void fs_private_dev(void){ | 64 | void fs_private_dev(void){ |
65 | int rv; | ||
65 | // install a new /dev directory | 66 | // install a new /dev directory |
66 | if (arg_debug) | 67 | if (arg_debug) |
67 | printf("Mounting tmpfs on /dev\n"); | 68 | printf("Mounting tmpfs on /dev\n"); |
68 | 69 | ||
70 | int have_dri = 0; | ||
71 | struct stat s; | ||
72 | if (stat("/dev/dri", &s) == 0) | ||
73 | have_dri = 1; | ||
74 | |||
69 | // create DRI_DIR | 75 | // create DRI_DIR |
70 | fs_build_mnt_dir(); | 76 | fs_build_mnt_dir(); |
71 | int rv = mkdir(DRI_DIR, 0755); | 77 | |
72 | if (rv == -1) | 78 | if (have_dri) { |
73 | errExit("mkdir"); | 79 | rv = mkdir(DRI_DIR, 0755); |
74 | if (chown(DRI_DIR, 0, 0) < 0) | 80 | if (rv == -1) |
75 | errExit("chown"); | 81 | errExit("mkdir"); |
76 | if (chmod(DRI_DIR, 0755) < 0) | 82 | if (chown(DRI_DIR, 0, 0) < 0) |
77 | errExit("chmod"); | 83 | errExit("chown"); |
78 | 84 | if (chmod(DRI_DIR, 0755) < 0) | |
79 | // keep a copy of /dev/dri under DRI_DIR | 85 | errExit("chmod"); |
80 | if (mount("/dev/dri", DRI_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | 86 | |
81 | errExit("mounting /dev"); | 87 | // keep a copy of /dev/dri under DRI_DIR |
82 | 88 | if (mount("/dev/dri", DRI_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | |
89 | errExit("mounting /dev/dri"); | ||
90 | } | ||
91 | |||
83 | // mount tmpfs on top of /dev | 92 | // mount tmpfs on top of /dev |
84 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | 93 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) |
85 | errExit("mounting /dev"); | 94 | errExit("mounting /dev"); |
86 | 95 | ||
87 | // bring back the /dev/dri directory | 96 | // bring back the /dev/dri directory |
88 | rv = mkdir("/dev/dri", 0755); | 97 | if (have_dri) { |
89 | if (rv == -1) | 98 | rv = mkdir("/dev/dri", 0755); |
90 | errExit("mkdir"); | 99 | if (rv == -1) |
91 | if (chown("/dev/dri", 0, 0) < 0) | 100 | errExit("mkdir"); |
92 | errExit("chown"); | 101 | if (chown("/dev/dri", 0, 0) < 0) |
93 | if (chmod("/dev/dri",0755) < 0) | 102 | errExit("chown"); |
94 | errExit("chmod"); | 103 | if (chmod("/dev/dri",0755) < 0) |
95 | if (mount(DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0) | 104 | errExit("chmod"); |
96 | errExit("mounting /dev"); | 105 | if (mount(DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0) |
106 | errExit("mounting /dev"); | ||
107 | } | ||
97 | 108 | ||
98 | // create /dev/shm | 109 | // create /dev/shm |
99 | if (arg_debug) | 110 | if (arg_debug) |
diff --git a/test/option-trace.exp b/test/option-trace.exp index 1d97df9b3..6efb2c545 100755 --- a/test/option-trace.exp +++ b/test/option-trace.exp | |||
@@ -11,7 +11,8 @@ expect { | |||
11 | } | 11 | } |
12 | expect { | 12 | expect { |
13 | timeout {puts "TESTING ERROR 1\n";exit} | 13 | timeout {puts "TESTING ERROR 1\n";exit} |
14 | "1:bash:open /dev/tty" | 14 | "1:bash:open /dev/tty" {puts "64bit\n"} |
15 | "1:bash:open64 /dev/tty" {puts "32bit\n"} | ||
15 | } | 16 | } |
16 | expect { | 17 | expect { |
17 | timeout {puts "TESTING ERROR 2\n";exit} | 18 | timeout {puts "TESTING ERROR 2\n";exit} |
@@ -24,4 +25,4 @@ expect { | |||
24 | 25 | ||
25 | sleep 1 | 26 | sleep 1 |
26 | 27 | ||
27 | puts "all done\n" | 28 | puts "\nall done\n" |
diff --git a/test/seccomp-errno.exp b/test/seccomp-errno.exp index 138f039b0..e6678ab8f 100755 --- a/test/seccomp-errno.exp +++ b/test/seccomp-errno.exp | |||
@@ -17,7 +17,7 @@ sleep 1 | |||
17 | send -- "firejail --seccomp.enoent=unlinkat --debug rm seccomp-test-file\r" | 17 | send -- "firejail --seccomp.enoent=unlinkat --debug rm seccomp-test-file\r" |
18 | expect { | 18 | expect { |
19 | timeout {puts "TESTING ERROR 1\n";exit} | 19 | timeout {puts "TESTING ERROR 1\n";exit} |
20 | "ERRNO 263 unlinkat 2 ENOENT" | 20 | "unlinkat 2 ENOENT" |
21 | } | 21 | } |
22 | sleep 1 | 22 | sleep 1 |
23 | 23 | ||
@@ -31,65 +31,10 @@ $ | |||
31 | 31 | ||
32 | 4. Remove exclude-token from profile include in 0.9.34 (deprecated in 0.9.30) | 32 | 4. Remove exclude-token from profile include in 0.9.34 (deprecated in 0.9.30) |
33 | 33 | ||
34 | 5. Debian 32bit compile with --enable-fatal-warnings | 34 | 5. Add IRC clients: KVIrc (KDE), BitchX (CLI), Smuxi, Konversation (KDE), HexChat, Irssi (CLI), WeeChat (CLI) |
35 | make[1]: Entering directory `/home/netblue/work/firejail-0.9.30/src/firejail' | ||
36 | cc -ggdb -W -Wall -Werror -O2 -DVERSION='"0.9.30"' -DPREFIX='"/usr"' -DHAVE_SECCOMP -DHAVE_CHROOT -DHAVE_BIND -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security -c seccomp.c -o seccomp.o | ||
37 | seccomp.c: In function ‘write_seccomp_file’: | ||
38 | seccomp.c:337:81: error: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘unsigned int’ [-Werror=format] | ||
39 | seccomp.c: In function ‘read_seccomp_file’: | ||
40 | seccomp.c:391:81: error: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘unsigned int’ [-Werror=format] | ||
41 | cc1: all warnings being treated as errors | ||
42 | make[1]: *** [seccomp.o] Error 1 | ||
43 | |||
44 | 6. Debian 32bit - multiple problems with the testing utility | ||
45 | |||
46 | 7. Add IRC clients: KVIrc (KDE), BitchX (CLI), Smuxi, Konversation (KDE), HexChat, Irssi (CLI), WeeChat (CLI) | ||
47 | RSS: Liferea, akregator (KDE), newsbeuter (CLI), rawdog, | 35 | RSS: Liferea, akregator (KDE), newsbeuter (CLI), rawdog, |
48 | 36 | ||
49 | 8. To investigate | 37 | 6. To investigate |
50 | void SupervisorMain::setupSeccomp() { | ||
51 | // Install a rudimentary seccomp blacklist. | ||
52 | // TODO(security): Change this to a whitelist. | ||
53 | |||
54 | scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW); | ||
55 | if (ctx == nullptr) | ||
56 | KJ_FAIL_SYSCALL("seccomp_init", 0); // No real error code | ||
57 | KJ_DEFER(seccomp_release(ctx)); | ||
58 | |||
59 | #define CHECK_SECCOMP(call) \ | ||
60 | do { \ | ||
61 | if (auto result = (call)) { \ | ||
62 | KJ_FAIL_SYSCALL(#call, -result); \ | ||
63 | } \ | ||
64 | } while (0) | ||
65 | |||
66 | // Native code only for now, so there are no seccomp_arch_add calls. | ||
67 | |||
68 | // Redundant, but this is standard and harmless. | ||
69 | CHECK_SECCOMP(seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 1)); | ||
70 | |||
71 | // It's easy to inadvertently issue an x32 syscall (e.g. syscall(-1)). Such syscalls | ||
72 | // should fail, but there's no need to kill the issuer. | ||
73 | CHECK_SECCOMP(seccomp_attr_set(ctx, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_ERRNO(ENOSYS))); | ||
74 | |||
75 | #pragma GCC diagnostic push | ||
76 | #pragma GCC diagnostic ignored "-Wmissing-field-initializers" // SCMP_* macros produce these | ||
77 | // Disable some things that seem scary. | ||
78 | if (!devmode) { | ||
79 | // ptrace is scary | ||
80 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 0)); | ||
81 | } else { | ||
82 | // Try to be somewhat safe with ptrace in dev mode. Note that the ability to modify | ||
83 | // orig_ax using ptrace allows a complete seccomp bypass. | ||
84 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, | ||
85 | SCMP_A0(SCMP_CMP_EQ, PTRACE_POKEUSER))); | ||
86 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, | ||
87 | SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGS))); | ||
88 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, | ||
89 | SCMP_A0(SCMP_CMP_EQ, PTRACE_SETFPREGS))); | ||
90 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, | ||
91 | SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGSET))); | ||
92 | } | ||
93 | 38 | ||
94 | // Restrict the set of allowable network protocol families | 39 | // Restrict the set of allowable network protocol families |
95 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, | 40 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, |
@@ -118,64 +63,3 @@ void SupervisorMain::setupSeccomp() { | |||
118 | SCMP_A0(SCMP_CMP_EQ, AF_SECURITY))); | 63 | SCMP_A0(SCMP_CMP_EQ, AF_SECURITY))); |
119 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, | 64 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, |
120 | SCMP_A0(SCMP_CMP_EQ, AF_KEY))); | 65 | SCMP_A0(SCMP_CMP_EQ, AF_KEY))); |
121 | #pragma GCC diagnostic pop | ||
122 | |||
123 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(add_key), 0)); | ||
124 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(request_key), 0)); | ||
125 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(keyctl), 0)); | ||
126 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(syslog), 0)); | ||
127 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(uselib), 0)); | ||
128 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(personality), 0)); | ||
129 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(acct), 0)); | ||
130 | |||
131 | // 16-bit code is unnecessary in the sandbox, and modify_ldt is a historic source | ||
132 | // of interesting information leaks. | ||
133 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(modify_ldt), 0)); | ||
134 | |||
135 | // Despite existing at a 64-bit syscall, set_thread_area is only useful | ||
136 | // for 32-bit programs. 64-bit programs use arch_prctl instead. | ||
137 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_thread_area), 0)); | ||
138 | |||
139 | // Disable namespaces. Nested sandboxing could be useful but the attack surface is large. | ||
140 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(unshare), 0)); | ||
141 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(mount), 0)); | ||
142 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(pivot_root), 0)); | ||
143 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(quotactl), 0)); | ||
144 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 1, | ||
145 | SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER))); | ||
146 | |||
147 | // AIO is scary. | ||
148 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_setup), 0)); | ||
149 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_destroy), 0)); | ||
150 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_getevents), 0)); | ||
151 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_submit), 0)); | ||
152 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_cancel), 0)); | ||
153 | |||
154 | // Scary vm syscalls | ||
155 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(remap_file_pages), 0)); | ||
156 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(mbind), 0)); | ||
157 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(get_mempolicy), 0)); | ||
158 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_mempolicy), 0)); | ||
159 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(migrate_pages), 0)); | ||
160 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(move_pages), 0)); | ||
161 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(vmsplice), 0)); | ||
162 | |||
163 | // Scary futex operations | ||
164 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_robust_list), 0)); | ||
165 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(get_robust_list), 0)); | ||
166 | |||
167 | // Utterly terrifying profiling operations | ||
168 | CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(perf_event_open), 0)); | ||
169 | |||
170 | // TOOD(someday): See if we can get away with turning off mincore, madvise, sysinfo etc. | ||
171 | |||
172 | // TODO(someday): Turn off POSIX message queues and other such esoteric features. | ||
173 | |||
174 | if (seccompDumpPfc) { | ||
175 | seccomp_export_pfc(ctx, 1); | ||
176 | } | ||
177 | |||
178 | CHECK_SECCOMP(seccomp_load(ctx)); | ||
179 | |||
180 | #undef CHECK_SECCOMP | ||
181 | } | ||