| 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> |
| (...skipping 16 matching lines...) Expand all Loading... |
| 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__) || \ |
| 29 (defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))) | 29 (defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))) |
| 30 #define SECCOMP_BPF_SANDBOX | 30 #define SECCOMP_BPF_SANDBOX |
| 31 #endif | 31 #endif |
| 32 | 32 |
| 33 #if defined(SECCOMP_BPF_SANDBOX) | 33 #if defined(SECCOMP_BPF_SANDBOX) |
| 34 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 34 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
| 35 #include "sandbox/linux/services/linux_syscalls.h" | 35 #include "sandbox/linux/services/linux_syscalls.h" |
| 36 | 36 |
| 37 using playground2::arch_seccomp_data; |
| 38 using playground2::ErrorCode; |
| 39 using playground2::Sandbox; |
| 40 |
| 37 namespace { | 41 namespace { |
| 38 | 42 |
| 39 inline bool IsChromeOS() { | 43 inline bool IsChromeOS() { |
| 40 #if defined(OS_CHROMEOS) | 44 #if defined(OS_CHROMEOS) |
| 41 return true; | 45 return true; |
| 42 #else | 46 #else |
| 43 return false; | 47 return false; |
| 44 #endif | 48 #endif |
| 45 } | 49 } |
| 46 | 50 |
| (...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 IsArmPciConfig(sysno) || | 1178 IsArmPciConfig(sysno) || |
| 1175 #endif | 1179 #endif |
| 1176 IsTimer(sysno)) { | 1180 IsTimer(sysno)) { |
| 1177 return true; | 1181 return true; |
| 1178 } else { | 1182 } else { |
| 1179 return false; | 1183 return false; |
| 1180 } | 1184 } |
| 1181 } | 1185 } |
| 1182 | 1186 |
| 1183 // x86_64 only for now. Needs to be adapted and tested for i386. | 1187 // x86_64 only for now. Needs to be adapted and tested for i386. |
| 1184 playground2::Sandbox::ErrorCode BaselinePolicy_x86_64(int sysno) { | 1188 ErrorCode BaselinePolicy_x86_64(int sysno) { |
| 1185 if (IsBaselinePolicyAllowed_x86_64(sysno)) { | 1189 if (IsBaselinePolicyAllowed_x86_64(sysno)) { |
| 1186 return playground2::Sandbox::SB_ALLOWED; | 1190 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1187 } | 1191 } |
| 1188 // TODO(jln): some system calls in those sets are not supposed to | 1192 // TODO(jln): some system calls in those sets are not supposed to |
| 1189 // return ENOENT. Return the appropriate error. | 1193 // return ENOENT. Return the appropriate error. |
| 1190 if (IsFileSystem(sysno) || IsCurrentDirectory(sysno)) { | 1194 if (IsFileSystem(sysno) || IsCurrentDirectory(sysno)) { |
| 1191 return ENOENT; | 1195 return ErrorCode(ENOENT); |
| 1192 } | 1196 } |
| 1193 | 1197 |
| 1194 if (IsUmask(sysno) || IsDeniedFileSystemAccessViaFd(sysno)) { | 1198 if (IsUmask(sysno) || IsDeniedFileSystemAccessViaFd(sysno)) { |
| 1195 return EPERM; | 1199 return ErrorCode(EPERM); |
| 1196 } | 1200 } |
| 1197 | 1201 |
| 1198 if (IsBaselinePolicyWatched_x86_64(sysno)) { | 1202 if (IsBaselinePolicyWatched_x86_64(sysno)) { |
| 1199 // Previously unseen syscalls. TODO(jln): some of these should | 1203 // Previously unseen syscalls. TODO(jln): some of these should |
| 1200 // be denied gracefully right away. | 1204 // be denied gracefully right away. |
| 1201 return playground2::Sandbox::ErrorCode(CrashSIGSYS_Handler, NULL); | 1205 return Sandbox::Trap(CrashSIGSYS_Handler, NULL); |
| 1202 } | 1206 } |
| 1203 // In any other case crash the program with our SIGSYS handler | 1207 // In any other case crash the program with our SIGSYS handler |
| 1204 return playground2::Sandbox::ErrorCode(CrashSIGSYS_Handler, NULL); | 1208 return Sandbox::Trap(CrashSIGSYS_Handler, NULL); |
| 1205 } | 1209 } |
| 1206 | 1210 |
| 1207 // x86_64 only for now. Needs to be adapted and tested for i386. | 1211 // x86_64 only for now. Needs to be adapted and tested for i386. |
| 1208 playground2::Sandbox::ErrorCode GpuProcessPolicy_x86_64(int sysno) { | 1212 ErrorCode GpuProcessPolicy_x86_64(int sysno) { |
| 1209 switch(sysno) { | 1213 switch(sysno) { |
| 1210 case __NR_ioctl: | 1214 case __NR_ioctl: |
| 1211 return playground2::Sandbox::SB_ALLOWED; | 1215 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1212 #if defined(__x86_64__) | 1216 #if defined(__x86_64__) |
| 1213 case __NR_socket: | 1217 case __NR_socket: |
| 1214 return EACCES; // Nvidia binary driver. | 1218 return ErrorCode(EACCES); // Nvidia binary driver. |
| 1215 #endif | 1219 #endif |
| 1216 case __NR_open: | 1220 case __NR_open: |
| 1217 // Accelerated video decode is enabled by default only on Chrome OS. | 1221 // Accelerated video decode is enabled by default only on Chrome OS. |
| 1218 if (IsAcceleratedVideoDecodeEnabled()) { | 1222 if (IsAcceleratedVideoDecodeEnabled()) { |
| 1219 // Accelerated video decode needs to open /dev/dri/card0, and | 1223 // Accelerated video decode needs to open /dev/dri/card0, and |
| 1220 // dup()'ing an already open file descriptor does not work. | 1224 // dup()'ing an already open file descriptor does not work. |
| 1221 // Allow open() even though it severely weakens the sandbox, | 1225 // Allow open() even though it severely weakens the sandbox, |
| 1222 // to test the sandboxing mechanism in general. | 1226 // to test the sandboxing mechanism in general. |
| 1223 // TODO(jorgelo): remove this once we solve the libva issue. | 1227 // TODO(jorgelo): remove this once we solve the libva issue. |
| 1224 return playground2::Sandbox::SB_ALLOWED; | 1228 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1225 } else { | 1229 } else { |
| 1226 // Hook open() in the GPU process to allow opening /etc/drirc, | 1230 // Hook open() in the GPU process to allow opening /etc/drirc, |
| 1227 // needed by Mesa. | 1231 // needed by Mesa. |
| 1228 // The hook needs dup(), lseek(), and close() to be allowed. | 1232 // The hook needs dup(), lseek(), and close() to be allowed. |
| 1229 return playground2::Sandbox::ErrorCode(GpuOpenSIGSYS_Handler, NULL); | 1233 return Sandbox::Trap(GpuOpenSIGSYS_Handler, NULL); |
| 1230 } | 1234 } |
| 1231 default: | 1235 default: |
| 1232 if (IsEventFd(sysno)) | 1236 if (IsEventFd(sysno)) |
| 1233 return playground2::Sandbox::SB_ALLOWED; | 1237 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1234 | 1238 |
| 1235 // Default on the baseline policy. | 1239 // Default on the baseline policy. |
| 1236 return BaselinePolicy_x86_64(sysno); | 1240 return BaselinePolicy_x86_64(sysno); |
| 1237 } | 1241 } |
| 1238 } | 1242 } |
| 1239 | 1243 |
| 1240 playground2::Sandbox::ErrorCode RendererProcessPolicy_x86_64(int sysno) { | 1244 ErrorCode RendererProcessPolicy_x86_64(int sysno) { |
| 1241 switch (sysno) { | 1245 switch (sysno) { |
| 1242 case __NR_ioctl: // TODO(jln) investigate legitimate use in the renderer | 1246 case __NR_ioctl: // TODO(jln) investigate legitimate use in the renderer |
| 1243 // and see if alternatives can be used. | 1247 // and see if alternatives can be used. |
| 1244 case __NR_fdatasync: | 1248 case __NR_fdatasync: |
| 1245 case __NR_fsync: | 1249 case __NR_fsync: |
| 1246 #if defined(__i386__) || defined(__x86_64__) | 1250 #if defined(__i386__) || defined(__x86_64__) |
| 1247 case __NR_getrlimit: | 1251 case __NR_getrlimit: |
| 1248 #endif | 1252 #endif |
| 1249 case __NR_pread64: | 1253 case __NR_pread64: |
| 1250 case __NR_pwrite64: | 1254 case __NR_pwrite64: |
| 1251 case __NR_sched_get_priority_max: | 1255 case __NR_sched_get_priority_max: |
| 1252 case __NR_sched_get_priority_min: | 1256 case __NR_sched_get_priority_min: |
| 1253 case __NR_sched_getparam: | 1257 case __NR_sched_getparam: |
| 1254 case __NR_sched_getscheduler: | 1258 case __NR_sched_getscheduler: |
| 1255 case __NR_sched_setscheduler: | 1259 case __NR_sched_setscheduler: |
| 1256 case __NR_setpriority: | 1260 case __NR_setpriority: |
| 1257 case __NR_sysinfo: | 1261 case __NR_sysinfo: |
| 1258 case __NR_times: | 1262 case __NR_times: |
| 1259 case __NR_uname: | 1263 case __NR_uname: |
| 1260 return playground2::Sandbox::SB_ALLOWED; | 1264 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1261 default: | 1265 default: |
| 1262 #if defined(__x86_64__) | 1266 #if defined(__x86_64__) |
| 1263 if (IsSystemVSharedMemory(sysno)) | 1267 if (IsSystemVSharedMemory(sysno)) |
| 1264 return playground2::Sandbox::SB_ALLOWED; | 1268 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1265 #endif | 1269 #endif |
| 1266 | 1270 |
| 1267 // Default on the baseline policy. | 1271 // Default on the baseline policy. |
| 1268 return BaselinePolicy_x86_64(sysno); | 1272 return BaselinePolicy_x86_64(sysno); |
| 1269 } | 1273 } |
| 1270 } | 1274 } |
| 1271 | 1275 |
| 1272 // x86_64 only for now. Needs to be adapted and tested for i386. | 1276 // x86_64 only for now. Needs to be adapted and tested for i386. |
| 1273 playground2::Sandbox::ErrorCode FlashProcessPolicy_x86_64(int sysno) { | 1277 ErrorCode FlashProcessPolicy_x86_64(int sysno) { |
| 1274 switch (sysno) { | 1278 switch (sysno) { |
| 1275 case __NR_sched_getaffinity: | 1279 case __NR_sched_getaffinity: |
| 1276 case __NR_sched_setscheduler: | 1280 case __NR_sched_setscheduler: |
| 1277 case __NR_times: | 1281 case __NR_times: |
| 1278 return playground2::Sandbox::SB_ALLOWED; | 1282 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1279 case __NR_ioctl: | 1283 case __NR_ioctl: |
| 1280 return ENOTTY; // Flash Access. | 1284 return ErrorCode(ENOTTY); // Flash Access. |
| 1281 #if defined(__x86_64__) | 1285 #if defined(__x86_64__) |
| 1282 case __NR_socket: | 1286 case __NR_socket: |
| 1283 return EACCES; | 1287 return ErrorCode(EACCES); |
| 1284 #endif | 1288 #endif |
| 1285 default: | 1289 default: |
| 1286 #if defined(__x86_64__) | 1290 #if defined(__x86_64__) |
| 1287 // These are under investigation, and hopefully not here for the long | 1291 // These are under investigation, and hopefully not here for the long |
| 1288 // term. | 1292 // term. |
| 1289 if (IsSystemVSharedMemory(sysno)) | 1293 if (IsSystemVSharedMemory(sysno)) |
| 1290 return playground2::Sandbox::SB_ALLOWED; | 1294 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1291 #endif | 1295 #endif |
| 1292 | 1296 |
| 1293 // Default on the baseline policy. | 1297 // Default on the baseline policy. |
| 1294 return BaselinePolicy_x86_64(sysno); | 1298 return BaselinePolicy_x86_64(sysno); |
| 1295 } | 1299 } |
| 1296 } | 1300 } |
| 1297 | 1301 |
| 1298 playground2::Sandbox::ErrorCode BlacklistDebugAndNumaPolicy(int sysno) { | 1302 ErrorCode BlacklistDebugAndNumaPolicy(int sysno) { |
| 1299 if (sysno < static_cast<int>(MIN_SYSCALL) || | 1303 if (sysno < static_cast<int>(MIN_SYSCALL) || |
| 1300 sysno > static_cast<int>(MAX_SYSCALL)) { | 1304 sysno > static_cast<int>(MAX_SYSCALL)) { |
| 1301 // TODO(jln) we should not have to do that in a trivial policy. | 1305 // TODO(jln) we should not have to do that in a trivial policy. |
| 1302 return ENOSYS; | 1306 return ErrorCode(ENOSYS); |
| 1303 } | 1307 } |
| 1304 | 1308 |
| 1305 if (IsDebug(sysno) || IsNuma(sysno)) | 1309 if (IsDebug(sysno) || IsNuma(sysno)) |
| 1306 return playground2::Sandbox::ErrorCode(CrashSIGSYS_Handler, NULL); | 1310 return Sandbox::Trap(CrashSIGSYS_Handler, NULL); |
| 1307 | 1311 |
| 1308 return playground2::Sandbox::SB_ALLOWED; | 1312 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1309 } | 1313 } |
| 1310 | 1314 |
| 1311 // Allow all syscalls. | 1315 // Allow all syscalls. |
| 1312 // This will still deny x32 or IA32 calls in 64 bits mode or | 1316 // This will still deny x32 or IA32 calls in 64 bits mode or |
| 1313 // 64 bits system calls in compatibility mode. | 1317 // 64 bits system calls in compatibility mode. |
| 1314 playground2::Sandbox::ErrorCode AllowAllPolicy(int sysno) { | 1318 ErrorCode AllowAllPolicy(int sysno) { |
| 1315 if (sysno < static_cast<int>(MIN_SYSCALL) || | 1319 if (sysno < static_cast<int>(MIN_SYSCALL) || |
| 1316 sysno > static_cast<int>(MAX_SYSCALL)) { | 1320 sysno > static_cast<int>(MAX_SYSCALL)) { |
| 1317 // TODO(jln) we should not have to do that in a trivial policy. | 1321 // TODO(jln) we should not have to do that in a trivial policy. |
| 1318 return ENOSYS; | 1322 return ErrorCode(ENOSYS); |
| 1319 } else { | 1323 } else { |
| 1320 return playground2::Sandbox::SB_ALLOWED; | 1324 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1321 } | 1325 } |
| 1322 } | 1326 } |
| 1323 | 1327 |
| 1324 // Warms up/preloads resources needed by the policies. | 1328 // Warms up/preloads resources needed by the policies. |
| 1325 void WarmupPolicy(playground2::Sandbox::EvaluateSyscall policy) { | 1329 void WarmupPolicy(Sandbox::EvaluateSyscall policy) { |
| 1326 #if defined(__x86_64__) | 1330 #if defined(__x86_64__) |
| 1327 if (policy == GpuProcessPolicy_x86_64) { | 1331 if (policy == GpuProcessPolicy_x86_64) { |
| 1328 OpenWithCache(kDriRcPath, O_RDONLY); | 1332 OpenWithCache(kDriRcPath, O_RDONLY); |
| 1329 // Accelerated video decode dlopen()'s this shared object | 1333 // Accelerated video decode dlopen()'s this shared object |
| 1330 // inside the sandbox, so preload it now. | 1334 // inside the sandbox, so preload it now. |
| 1331 // TODO(jorgelo): generalize this to other platforms. | 1335 // TODO(jorgelo): generalize this to other platforms. |
| 1332 if (IsAcceleratedVideoDecodeEnabled()) { | 1336 if (IsAcceleratedVideoDecodeEnabled()) { |
| 1333 const char kI965DrvVideoPath_64[] = | 1337 const char kI965DrvVideoPath_64[] = |
| 1334 "/usr/lib64/va/drivers/i965_drv_video.so"; | 1338 "/usr/lib64/va/drivers/i965_drv_video.so"; |
| 1335 dlopen(kI965DrvVideoPath_64, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | 1339 dlopen(kI965DrvVideoPath_64, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); |
| 1336 } | 1340 } |
| 1337 } | 1341 } |
| 1338 #endif | 1342 #endif |
| 1339 } | 1343 } |
| 1340 | 1344 |
| 1341 playground2::Sandbox::EvaluateSyscall GetProcessSyscallPolicy( | 1345 Sandbox::EvaluateSyscall GetProcessSyscallPolicy( |
| 1342 const CommandLine& command_line, | 1346 const CommandLine& command_line, |
| 1343 const std::string& process_type) { | 1347 const std::string& process_type) { |
| 1344 #if defined(__x86_64__) | 1348 #if defined(__x86_64__) |
| 1345 if (process_type == switches::kGpuProcess) { | 1349 if (process_type == switches::kGpuProcess) { |
| 1346 // On Chrome OS, --enable-gpu-sandbox enables the more restrictive policy. | 1350 // On Chrome OS, --enable-gpu-sandbox enables the more restrictive policy. |
| 1347 if (IsChromeOS() && !command_line.HasSwitch(switches::kEnableGpuSandbox)) | 1351 if (IsChromeOS() && !command_line.HasSwitch(switches::kEnableGpuSandbox)) |
| 1348 return BlacklistDebugAndNumaPolicy; | 1352 return BlacklistDebugAndNumaPolicy; |
| 1349 else | 1353 else |
| 1350 return GpuProcessPolicy_x86_64; | 1354 return GpuProcessPolicy_x86_64; |
| 1351 } | 1355 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1370 // On other architectures (currently IA32 or ARM), | 1374 // On other architectures (currently IA32 or ARM), |
| 1371 // we only have a small blacklist at the moment. | 1375 // we only have a small blacklist at the moment. |
| 1372 (void) process_type; | 1376 (void) process_type; |
| 1373 return BlacklistDebugAndNumaPolicy; | 1377 return BlacklistDebugAndNumaPolicy; |
| 1374 #endif // __x86_64__ | 1378 #endif // __x86_64__ |
| 1375 } | 1379 } |
| 1376 | 1380 |
| 1377 // Initialize the seccomp-bpf sandbox. | 1381 // Initialize the seccomp-bpf sandbox. |
| 1378 bool StartBpfSandbox(const CommandLine& command_line, | 1382 bool StartBpfSandbox(const CommandLine& command_line, |
| 1379 const std::string& process_type) { | 1383 const std::string& process_type) { |
| 1380 playground2::Sandbox::EvaluateSyscall SyscallPolicy = | 1384 Sandbox::EvaluateSyscall SyscallPolicy = |
| 1381 GetProcessSyscallPolicy(command_line, process_type); | 1385 GetProcessSyscallPolicy(command_line, process_type); |
| 1382 | 1386 |
| 1383 // Warms up resources needed by the policy we're about to enable. | 1387 // Warms up resources needed by the policy we're about to enable. |
| 1384 WarmupPolicy(SyscallPolicy); | 1388 WarmupPolicy(SyscallPolicy); |
| 1385 | 1389 |
| 1386 playground2::Sandbox::setSandboxPolicy(SyscallPolicy, NULL); | 1390 Sandbox::setSandboxPolicy(SyscallPolicy, NULL); |
| 1387 playground2::Sandbox::startSandbox(); | 1391 Sandbox::startSandbox(); |
| 1388 | 1392 |
| 1389 return true; | 1393 return true; |
| 1390 } | 1394 } |
| 1391 | 1395 |
| 1392 } // namespace | 1396 } // namespace |
| 1393 | 1397 |
| 1394 #endif // SECCOMP_BPF_SANDBOX | 1398 #endif // SECCOMP_BPF_SANDBOX |
| 1395 | 1399 |
| 1396 namespace content { | 1400 namespace content { |
| 1397 | 1401 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1415 | 1419 |
| 1416 return true; | 1420 return true; |
| 1417 #endif | 1421 #endif |
| 1418 return false; | 1422 return false; |
| 1419 } | 1423 } |
| 1420 | 1424 |
| 1421 bool SandboxSeccompBpf::SupportsSandbox() { | 1425 bool SandboxSeccompBpf::SupportsSandbox() { |
| 1422 #if defined(SECCOMP_BPF_SANDBOX) | 1426 #if defined(SECCOMP_BPF_SANDBOX) |
| 1423 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton | 1427 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton |
| 1424 // here. | 1428 // here. |
| 1425 if (playground2::Sandbox::supportsSeccompSandbox(-1) == | 1429 if (Sandbox::supportsSeccompSandbox(-1) == |
| 1426 playground2::Sandbox::STATUS_AVAILABLE) { | 1430 Sandbox::STATUS_AVAILABLE) { |
| 1427 return true; | 1431 return true; |
| 1428 } | 1432 } |
| 1429 #endif | 1433 #endif |
| 1430 return false; | 1434 return false; |
| 1431 } | 1435 } |
| 1432 | 1436 |
| 1433 bool SandboxSeccompBpf::StartSandbox(const std::string& process_type) { | 1437 bool SandboxSeccompBpf::StartSandbox(const std::string& process_type) { |
| 1434 #if defined(SECCOMP_BPF_SANDBOX) | 1438 #if defined(SECCOMP_BPF_SANDBOX) |
| 1435 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 1439 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 1436 | 1440 |
| 1437 if (IsSeccompBpfDesired() && // Global switches policy. | 1441 if (IsSeccompBpfDesired() && // Global switches policy. |
| 1438 // Process-specific policy. | 1442 // Process-specific policy. |
| 1439 ShouldEnableSeccompBpf(process_type) && | 1443 ShouldEnableSeccompBpf(process_type) && |
| 1440 SupportsSandbox()) { | 1444 SupportsSandbox()) { |
| 1441 return StartBpfSandbox(command_line, process_type); | 1445 return StartBpfSandbox(command_line, process_type); |
| 1442 } | 1446 } |
| 1443 #endif | 1447 #endif |
| 1444 return false; | 1448 return false; |
| 1445 } | 1449 } |
| 1446 | 1450 |
| 1447 } // namespace content | 1451 } // namespace content |
| OLD | NEW |