OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <asm/unistd.h> | 5 #include <asm/unistd.h> |
6 #include <dlfcn.h> | 6 #include <dlfcn.h> |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <linux/audit.h> | 9 #include <linux/audit.h> |
10 #include <linux/filter.h> | 10 #include <linux/filter.h> |
11 #include <signal.h> | 11 #include <signal.h> |
12 #include <string.h> | 12 #include <string.h> |
13 #include <sys/prctl.h> | 13 #include <sys/prctl.h> |
14 #include <sys/stat.h> | 14 #include <sys/stat.h> |
15 #include <sys/types.h> | 15 #include <sys/types.h> |
16 #include <ucontext.h> | 16 #include <ucontext.h> |
17 #include <unistd.h> | 17 #include <unistd.h> |
18 | 18 |
19 #include <vector> | 19 #include <vector> |
20 | 20 |
21 #include "base/command_line.h" | 21 #include "base/command_line.h" |
22 #include "base/logging.h" | 22 #include "base/logging.h" |
23 #include "content/common/sandbox_linux.h" | 23 #include "content/common/sandbox_linux.h" |
24 #include "content/common/sandbox_seccomp_bpf_linux.h" | 24 #include "content/common/sandbox_seccomp_bpf_linux.h" |
25 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
26 | 26 |
27 // These are the only architectures supported for now. | 27 // These are the only architectures supported for now. |
28 #if defined(__i386__) || defined(__x86_64__) | 28 #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) |
29 #define SECCOMP_BPF_SANDBOX | 29 #define SECCOMP_BPF_SANDBOX |
30 #endif | 30 #endif |
31 | 31 |
32 #if defined(SECCOMP_BPF_SANDBOX) | 32 #if defined(SECCOMP_BPF_SANDBOX) |
33 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 33 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
34 | |
35 #if defined(__i386__) || defined(__x86_64__) | |
34 #include "sandbox/linux/services/x86_linux_syscalls.h" | 36 #include "sandbox/linux/services/x86_linux_syscalls.h" |
37 #elif defined(__arm__) | |
38 #include "sandbox/linux/services/arm_linux_syscalls.h" | |
jln (very slow on Chromium)
2012/08/14 20:11:50
Once you're confident arm is well covered, please
Jorge Lucangeli Obes
2012/08/14 21:58:06
Will do.
| |
39 #endif | |
35 | 40 |
36 namespace { | 41 namespace { |
37 | 42 |
38 inline bool IsChromeOS() { | 43 inline bool IsChromeOS() { |
39 #if defined(OS_CHROMEOS) | 44 #if defined(OS_CHROMEOS) |
40 return true; | 45 return true; |
41 #else | 46 #else |
42 return false; | 47 return false; |
43 #endif | 48 #endif |
44 } | 49 } |
45 | 50 |
51 inline bool IsARM() { | |
jln (very slow on Chromium)
2012/08/14 19:10:35
You're not using it at the moment.
Jorge Lucangeli Obes
2012/08/14 21:58:06
Done.
| |
52 #if defined(__arm__) | |
53 return true; | |
54 #else | |
55 return false; | |
56 #endif | |
57 } | |
58 | |
46 intptr_t CrashSIGSYS_Handler(const struct arch_seccomp_data& args, void* aux) { | 59 intptr_t CrashSIGSYS_Handler(const struct arch_seccomp_data& args, void* aux) { |
47 int syscall = args.nr; | 60 int syscall = args.nr; |
48 if (syscall >= 1024) | 61 if (syscall >= 1024) |
49 syscall = 0; | 62 syscall = 0; |
50 // Encode 8-bits of the 1st two arguments too, so we can discern which socket | 63 // Encode 8-bits of the 1st two arguments too, so we can discern which socket |
51 // type, which fcntl, ... etc., without being likely to hit a mapped | 64 // type, which fcntl, ... etc., without being likely to hit a mapped |
52 // address. | 65 // address. |
53 // Do not encode more bits here without thinking about increasing the | 66 // Do not encode more bits here without thinking about increasing the |
54 // likelihood of collision with mapped pages. | 67 // likelihood of collision with mapped pages. |
55 syscall |= ((args.args[0] & 0xffUL) << 12); | 68 syscall |= ((args.args[0] & 0xffUL) << 12); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 int flags = static_cast<int>(arg1); | 153 int flags = static_cast<int>(arg1); |
141 | 154 |
142 if (strcmp(pathname, kDriRcPath) == 0) { | 155 if (strcmp(pathname, kDriRcPath) == 0) { |
143 int ret = OpenWithCache(pathname, flags); | 156 int ret = OpenWithCache(pathname, flags); |
144 return (ret == -1) ? -errno : ret; | 157 return (ret == -1) ? -errno : ret; |
145 } else { | 158 } else { |
146 return -ENOENT; | 159 return -ENOENT; |
147 } | 160 } |
148 } | 161 } |
149 | 162 |
150 #if defined(__i386__) || defined(__x86_64__) | 163 #if defined(__i386__) || defined(__x86_64__) |
jln (very slow on Chromium)
2012/08/14 19:10:35
Did you miss this?
| |
151 | 164 |
152 // The functions below cover all existing x86_64 and i386 system calls. | 165 // The functions below cover all existing x86_64 and i386 system calls. |
153 // The implicitly defined sets form a partition of the sets of | 166 // The implicitly defined sets form a partition of the sets of |
154 // system calls. | 167 // system calls. |
jln (very slow on Chromium)
2012/08/14 19:10:35
Also you probably want to add something to this co
| |
155 | 168 |
156 // TODO(jln) we need to restrict the first parameter! | 169 // TODO(jln) we need to restrict the first parameter! |
157 bool IsKill(int sysno) { | 170 bool IsKill(int sysno) { |
158 switch (sysno) { | 171 switch (sysno) { |
159 case __NR_kill: | 172 case __NR_kill: |
160 case __NR_tkill: | 173 case __NR_tkill: |
161 case __NR_tgkill: | 174 case __NR_tgkill: |
162 return true; | 175 return true; |
163 default: | 176 default: |
164 return false; | 177 return false; |
165 } | 178 } |
166 } | 179 } |
167 | 180 |
168 bool IsAllowedGettime(int sysno) { | 181 bool IsAllowedGettime(int sysno) { |
169 switch (sysno) { | 182 switch (sysno) { |
170 case __NR_clock_gettime: | 183 case __NR_clock_gettime: |
171 case __NR_gettimeofday: | 184 case __NR_gettimeofday: |
185 // __NR_time is not available for EABI ARM. | |
186 // See </arch/arm/include/asm/unistd.h> in the Linux kernel. | |
187 #if !defined(__arm__) | |
jln (very slow on Chromium)
2012/08/14 19:10:35
It's better to whitelist: #if defined(__i386__) ||
Jorge Lucangeli Obes
2012/08/14 21:58:06
Done.
| |
172 case __NR_time: | 188 case __NR_time: |
189 #endif | |
173 return true; | 190 return true; |
174 case __NR_adjtimex: // Privileged. | 191 case __NR_adjtimex: // Privileged. |
175 case __NR_clock_adjtime: // Privileged. | 192 case __NR_clock_adjtime: // Privileged. |
176 case __NR_clock_getres: // Could be allowed. | 193 case __NR_clock_getres: // Could be allowed. |
177 case __NR_clock_nanosleep: // Could be allowed. | 194 case __NR_clock_nanosleep: // Could be allowed. |
178 case __NR_clock_settime: // Privileged. | 195 case __NR_clock_settime: // Privileged. |
179 #if defined(__i386__) | 196 #if defined(__i386__) |
180 case __NR_ftime: // Obsolete. | 197 case __NR_ftime: // Obsolete. |
181 #endif | 198 #endif |
182 case __NR_settimeofday: // Privileged. | 199 case __NR_settimeofday: // Privileged. |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
737 default: | 754 default: |
738 return false; | 755 return false; |
739 } | 756 } |
740 } | 757 } |
741 | 758 |
742 bool IsNuma(int sysno) { | 759 bool IsNuma(int sysno) { |
743 switch (sysno) { | 760 switch (sysno) { |
744 case __NR_get_mempolicy: | 761 case __NR_get_mempolicy: |
745 case __NR_getcpu: | 762 case __NR_getcpu: |
746 case __NR_mbind: | 763 case __NR_mbind: |
764 // __NR_migrate_pages is not available for EABI ARM. | |
765 // See </arch/arm/include/asm/unistd.h> in the Linux kernel. | |
766 #if !defined(__arm__) | |
jln (very slow on Chromium)
2012/08/14 19:10:35
Same here.
Jorge Lucangeli Obes
2012/08/14 21:58:06
Done.
| |
747 case __NR_migrate_pages: | 767 case __NR_migrate_pages: |
768 #endif | |
748 case __NR_move_pages: | 769 case __NR_move_pages: |
749 case __NR_set_mempolicy: | 770 case __NR_set_mempolicy: |
750 return true; | 771 return true; |
751 default: | 772 default: |
752 return false; | 773 return false; |
753 } | 774 } |
754 } | 775 } |
755 | 776 |
756 bool IsMessageQueue(int sysno) { | 777 bool IsMessageQueue(int sysno) { |
757 switch (sysno) { | 778 switch (sysno) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
928 case __NR_inotify_add_watch: | 949 case __NR_inotify_add_watch: |
929 case __NR_inotify_init: | 950 case __NR_inotify_init: |
930 case __NR_inotify_init1: | 951 case __NR_inotify_init1: |
931 case __NR_inotify_rm_watch: | 952 case __NR_inotify_rm_watch: |
932 return true; | 953 return true; |
933 default: | 954 default: |
934 return false; | 955 return false; |
935 } | 956 } |
936 } | 957 } |
937 | 958 |
959 void LogSandboxStarted(const std::string& sandbox_name, | |
jln (very slow on Chromium)
2012/08/14 19:10:35
Rebase issue ? This should not exist in this file.
Jorge Lucangeli Obes
2012/08/14 21:58:06
Done.
| |
960 const std::string& process_type) { | |
961 const std::string activated_sandbox = | |
962 "Activated " + sandbox_name + " sandbox for process type: " + | |
963 process_type + "."; | |
964 if (IsChromeOS()) { | |
965 LOG(WARNING) << activated_sandbox; | |
966 } else { | |
967 VLOG(1) << activated_sandbox; | |
968 } | |
969 } | |
970 | |
938 bool IsFaNotify(int sysno) { | 971 bool IsFaNotify(int sysno) { |
939 switch (sysno) { | 972 switch (sysno) { |
940 case __NR_fanotify_init: | 973 case __NR_fanotify_init: |
941 case __NR_fanotify_mark: | 974 case __NR_fanotify_mark: |
942 return true; | 975 return true; |
943 default: | 976 default: |
944 return false; | 977 return false; |
945 } | 978 } |
946 } | 979 } |
947 | 980 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1185 } | 1218 } |
1186 #endif // defined(__x86_64__) || defined(__i386__) | 1219 #endif // defined(__x86_64__) || defined(__i386__) |
1187 | 1220 |
1188 playground2::Sandbox::ErrorCode BlacklistPtracePolicy(int sysno) { | 1221 playground2::Sandbox::ErrorCode BlacklistPtracePolicy(int sysno) { |
1189 if (sysno < static_cast<int>(MIN_SYSCALL) || | 1222 if (sysno < static_cast<int>(MIN_SYSCALL) || |
1190 sysno > static_cast<int>(MAX_SYSCALL)) { | 1223 sysno > static_cast<int>(MAX_SYSCALL)) { |
1191 // TODO(jln) we should not have to do that in a trivial policy. | 1224 // TODO(jln) we should not have to do that in a trivial policy. |
1192 return ENOSYS; | 1225 return ENOSYS; |
1193 } | 1226 } |
1194 switch (sysno) { | 1227 switch (sysno) { |
1228 // __NR_migrate_pages is not available for EABI ARM. | |
1229 // See </arch/arm/include/asm/unistd.h> in the Linux kernel. | |
1230 #if !defined(__arm__) | |
jln (very slow on Chromium)
2012/08/14 19:10:35
Same remark about whitelisting.
Jorge Lucangeli Obes
2012/08/14 21:58:06
Done.
| |
1195 case __NR_migrate_pages: | 1231 case __NR_migrate_pages: |
1232 #endif | |
1196 case __NR_move_pages: | 1233 case __NR_move_pages: |
1197 case __NR_process_vm_readv: | 1234 case __NR_process_vm_readv: |
1198 case __NR_process_vm_writev: | 1235 case __NR_process_vm_writev: |
1199 case __NR_ptrace: | 1236 case __NR_ptrace: |
1200 return playground2::Sandbox::ErrorCode(CrashSIGSYS_Handler, NULL); | 1237 return playground2::Sandbox::ErrorCode(CrashSIGSYS_Handler, NULL); |
1201 default: | 1238 default: |
1202 return playground2::Sandbox::SB_ALLOWED; | 1239 return playground2::Sandbox::SB_ALLOWED; |
1203 } | 1240 } |
1204 } | 1241 } |
1205 | 1242 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1251 return FlashProcessPolicy_x86_64; | 1288 return FlashProcessPolicy_x86_64; |
1252 } | 1289 } |
1253 | 1290 |
1254 if (process_type == switches::kRendererProcess || | 1291 if (process_type == switches::kRendererProcess || |
1255 process_type == switches::kWorkerProcess) { | 1292 process_type == switches::kWorkerProcess) { |
1256 return BlacklistPtracePolicy; | 1293 return BlacklistPtracePolicy; |
1257 } | 1294 } |
1258 NOTREACHED(); | 1295 NOTREACHED(); |
1259 // This will be our default if we need one. | 1296 // This will be our default if we need one. |
1260 return AllowAllPolicy; | 1297 return AllowAllPolicy; |
1261 #else | 1298 #elif defined(__i386__) |
1262 // On IA32, we only have a small blacklist at the moment. | 1299 // On IA32, we only have a small blacklist at the moment. |
1263 (void) process_type; | 1300 (void) process_type; |
1264 return BlacklistPtracePolicy; | 1301 return BlacklistPtracePolicy; |
1265 #endif // __x86_64__ | 1302 #elif defined(__arm__) |
1303 // On ARM, we don't block anything yet. | |
jln (very slow on Chromium)
2012/08/14 19:10:35
This seems at odd with what you're doing. Did you
Jorge Lucangeli Obes
2012/08/14 21:58:06
Done.
| |
1304 (void) process_type; | |
1305 return BlacklistPtracePolicy; | |
1306 #else | |
1307 // This should not happen, we're compiling only on x86_64 or i386 or ARM. | |
1308 (void) process_type; | |
1309 NOTREACHED(); | |
1310 #endif | |
1266 } | 1311 } |
1267 | 1312 |
1268 // Initialize the seccomp-bpf sandbox. | 1313 // Initialize the seccomp-bpf sandbox. |
1269 bool StartBpfSandbox_x86(const CommandLine& command_line, | 1314 bool StartBpfSandbox(const CommandLine& command_line, |
1270 const std::string& process_type) { | 1315 const std::string& process_type) { |
1271 playground2::Sandbox::EvaluateSyscall SyscallPolicy = | 1316 playground2::Sandbox::EvaluateSyscall SyscallPolicy = |
1272 GetProcessSyscallPolicy(command_line, process_type); | 1317 GetProcessSyscallPolicy(command_line, process_type); |
1273 | 1318 |
1274 // Warms up resources needed by the policy we're about to enable. | 1319 // Warms up resources needed by the policy we're about to enable. |
1275 WarmupPolicy(SyscallPolicy); | 1320 WarmupPolicy(SyscallPolicy); |
1276 | 1321 |
1277 playground2::Sandbox::setSandboxPolicy(SyscallPolicy, NULL); | 1322 playground2::Sandbox::setSandboxPolicy(SyscallPolicy, NULL); |
1278 playground2::Sandbox::startSandbox(); | 1323 playground2::Sandbox::startSandbox(); |
1279 | 1324 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1322 } | 1367 } |
1323 | 1368 |
1324 bool SandboxSeccompBpf::StartSandbox(const std::string& process_type) { | 1369 bool SandboxSeccompBpf::StartSandbox(const std::string& process_type) { |
1325 #if defined(SECCOMP_BPF_SANDBOX) | 1370 #if defined(SECCOMP_BPF_SANDBOX) |
1326 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 1371 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
1327 | 1372 |
1328 if (IsSeccompBpfDesired() && // Global switches policy. | 1373 if (IsSeccompBpfDesired() && // Global switches policy. |
1329 // Process-specific policy. | 1374 // Process-specific policy. |
1330 ShouldEnableSeccompBpf(process_type) && | 1375 ShouldEnableSeccompBpf(process_type) && |
1331 SupportsSandbox()) { | 1376 SupportsSandbox()) { |
1332 return StartBpfSandbox_x86(command_line, process_type); | 1377 return StartBpfSandbox(command_line, process_type); |
1333 } | 1378 } |
1334 #endif | 1379 #endif |
1335 return false; | 1380 return false; |
1336 } | 1381 } |
1337 | 1382 |
1338 } // namespace content | 1383 } // namespace content |
OLD | NEW |