| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" | 5 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/mman.h> | 8 #include <sys/mman.h> |
| 9 #include <sys/socket.h> |
| 10 #include <sys/syscall.h> |
| 9 #include <sys/types.h> | 11 #include <sys/types.h> |
| 10 #include <sys/socket.h> | 12 #include <unistd.h> |
| 11 | 13 |
| 12 #include "base/logging.h" | 14 #include "base/logging.h" |
| 13 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 14 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" | 16 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" |
| 15 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" | 17 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" |
| 16 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" | 18 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" |
| 17 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 19 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
| 18 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" | 20 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" |
| 19 #include "sandbox/linux/services/linux_syscalls.h" | 21 #include "sandbox/linux/services/linux_syscalls.h" |
| 20 | 22 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 35 SyscallSets::IsAllowedGettime(sysno) || | 37 SyscallSets::IsAllowedGettime(sysno) || |
| 36 SyscallSets::IsAllowedPrctl(sysno) || | 38 SyscallSets::IsAllowedPrctl(sysno) || |
| 37 SyscallSets::IsAllowedProcessStartOrDeath(sysno) || | 39 SyscallSets::IsAllowedProcessStartOrDeath(sysno) || |
| 38 SyscallSets::IsAllowedSignalHandling(sysno) || | 40 SyscallSets::IsAllowedSignalHandling(sysno) || |
| 39 SyscallSets::IsFutex(sysno) || | 41 SyscallSets::IsFutex(sysno) || |
| 40 SyscallSets::IsGetSimpleId(sysno) || | 42 SyscallSets::IsGetSimpleId(sysno) || |
| 41 SyscallSets::IsKernelInternalApi(sysno) || | 43 SyscallSets::IsKernelInternalApi(sysno) || |
| 42 #if defined(__arm__) | 44 #if defined(__arm__) |
| 43 SyscallSets::IsArmPrivate(sysno) || | 45 SyscallSets::IsArmPrivate(sysno) || |
| 44 #endif | 46 #endif |
| 45 SyscallSets::IsKill(sysno) || | |
| 46 SyscallSets::IsAllowedOperationOnFd(sysno); | 47 SyscallSets::IsAllowedOperationOnFd(sysno); |
| 47 } | 48 } |
| 48 | 49 |
| 49 // System calls that will trigger the crashing SIGSYS handler. | 50 // System calls that will trigger the crashing SIGSYS handler. |
| 50 bool IsBaselinePolicyWatched(int sysno) { | 51 bool IsBaselinePolicyWatched(int sysno) { |
| 51 return SyscallSets::IsAdminOperation(sysno) || | 52 return SyscallSets::IsAdminOperation(sysno) || |
| 52 SyscallSets::IsAdvancedScheduler(sysno) || | 53 SyscallSets::IsAdvancedScheduler(sysno) || |
| 53 SyscallSets::IsAdvancedTimer(sysno) || | 54 SyscallSets::IsAdvancedTimer(sysno) || |
| 54 SyscallSets::IsAsyncIo(sysno) || | 55 SyscallSets::IsAsyncIo(sysno) || |
| 55 SyscallSets::IsDebug(sysno) || | 56 SyscallSets::IsDebug(sysno) || |
| 56 SyscallSets::IsEventFd(sysno) || | 57 SyscallSets::IsEventFd(sysno) || |
| 57 SyscallSets::IsExtendedAttributes(sysno) || | 58 SyscallSets::IsExtendedAttributes(sysno) || |
| 58 SyscallSets::IsFaNotify(sysno) || | 59 SyscallSets::IsFaNotify(sysno) || |
| 59 SyscallSets::IsFsControl(sysno) || | 60 SyscallSets::IsFsControl(sysno) || |
| 60 SyscallSets::IsGlobalFSViewChange(sysno) || | 61 SyscallSets::IsGlobalFSViewChange(sysno) || |
| 61 SyscallSets::IsGlobalProcessEnvironment(sysno) || | 62 SyscallSets::IsGlobalProcessEnvironment(sysno) || |
| 62 SyscallSets::IsGlobalSystemStatus(sysno) || | 63 SyscallSets::IsGlobalSystemStatus(sysno) || |
| 63 SyscallSets::IsInotify(sysno) || | 64 SyscallSets::IsInotify(sysno) || |
| 64 SyscallSets::IsKernelModule(sysno) || | 65 SyscallSets::IsKernelModule(sysno) || |
| 65 SyscallSets::IsKeyManagement(sysno) || | 66 SyscallSets::IsKeyManagement(sysno) || |
| 67 SyscallSets::IsKill(sysno) || |
| 66 SyscallSets::IsMessageQueue(sysno) || | 68 SyscallSets::IsMessageQueue(sysno) || |
| 67 SyscallSets::IsMisc(sysno) || | 69 SyscallSets::IsMisc(sysno) || |
| 68 #if defined(__x86_64__) | 70 #if defined(__x86_64__) |
| 69 SyscallSets::IsNetworkSocketInformation(sysno) || | 71 SyscallSets::IsNetworkSocketInformation(sysno) || |
| 70 #endif | 72 #endif |
| 71 SyscallSets::IsNuma(sysno) || | 73 SyscallSets::IsNuma(sysno) || |
| 72 SyscallSets::IsProcessGroupOrSession(sysno) || | 74 SyscallSets::IsProcessGroupOrSession(sysno) || |
| 73 #if defined(__i386__) | 75 #if defined(__i386__) |
| 74 SyscallSets::IsSocketCall(sysno) || | 76 SyscallSets::IsSocketCall(sysno) || |
| 75 #endif | 77 #endif |
| 76 #if defined(__arm__) | 78 #if defined(__arm__) |
| 77 SyscallSets::IsArmPciConfig(sysno) || | 79 SyscallSets::IsArmPciConfig(sysno) || |
| 78 #endif | 80 #endif |
| 79 SyscallSets::IsTimer(sysno); | 81 SyscallSets::IsTimer(sysno); |
| 80 } | 82 } |
| 81 | 83 |
| 82 // |fs_denied_errno| is the errno return for denied filesystem access. | 84 // |fs_denied_errno| is the errno return for denied filesystem access. |
| 83 ErrorCode EvaluateSyscallImpl(int fs_denied_errno, SandboxBPF* sandbox, | 85 ErrorCode EvaluateSyscallImpl(int fs_denied_errno, |
| 86 pid_t current_pid, |
| 87 SandboxBPF* sandbox, |
| 84 int sysno) { | 88 int sysno) { |
| 85 if (IsBaselinePolicyAllowed(sysno)) { | 89 if (IsBaselinePolicyAllowed(sysno)) { |
| 86 return ErrorCode(ErrorCode::ERR_ALLOWED); | 90 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 87 } | 91 } |
| 88 | 92 |
| 89 #if defined(__x86_64__) || defined(__arm__) | 93 #if defined(__x86_64__) || defined(__arm__) |
| 90 if (sysno == __NR_socketpair) { | 94 if (sysno == __NR_socketpair) { |
| 91 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. | 95 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen. |
| 92 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different); | 96 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different); |
| 93 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX, | 97 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 118 return RestrictMprotectFlags(sandbox); | 122 return RestrictMprotectFlags(sandbox); |
| 119 | 123 |
| 120 if (sysno == __NR_fcntl) | 124 if (sysno == __NR_fcntl) |
| 121 return RestrictFcntlCommands(sandbox); | 125 return RestrictFcntlCommands(sandbox); |
| 122 | 126 |
| 123 #if defined(__i386__) || defined(__arm__) | 127 #if defined(__i386__) || defined(__arm__) |
| 124 if (sysno == __NR_fcntl64) | 128 if (sysno == __NR_fcntl64) |
| 125 return RestrictFcntlCommands(sandbox); | 129 return RestrictFcntlCommands(sandbox); |
| 126 #endif | 130 #endif |
| 127 | 131 |
| 132 if (SyscallSets::IsKill(sysno)) { |
| 133 return RestrictKillTarget(current_pid, sandbox, sysno); |
| 134 } |
| 135 |
| 128 if (SyscallSets::IsFileSystem(sysno) || | 136 if (SyscallSets::IsFileSystem(sysno) || |
| 129 SyscallSets::IsCurrentDirectory(sysno)) { | 137 SyscallSets::IsCurrentDirectory(sysno)) { |
| 130 return ErrorCode(fs_denied_errno); | 138 return ErrorCode(fs_denied_errno); |
| 131 } | 139 } |
| 132 | 140 |
| 133 if (SyscallSets::IsAnySystemV(sysno)) { | 141 if (SyscallSets::IsAnySystemV(sysno)) { |
| 134 return ErrorCode(EPERM); | 142 return ErrorCode(EPERM); |
| 135 } | 143 } |
| 136 | 144 |
| 137 if (SyscallSets::IsUmask(sysno) || | 145 if (SyscallSets::IsUmask(sysno) || |
| 138 SyscallSets::IsDeniedFileSystemAccessViaFd(sysno) || | 146 SyscallSets::IsDeniedFileSystemAccessViaFd(sysno) || |
| 139 SyscallSets::IsDeniedGetOrModifySocket(sysno) || | 147 SyscallSets::IsDeniedGetOrModifySocket(sysno) || |
| 140 SyscallSets::IsProcessPrivilegeChange(sysno)) { | 148 SyscallSets::IsProcessPrivilegeChange(sysno)) { |
| 141 return ErrorCode(EPERM); | 149 return ErrorCode(EPERM); |
| 142 } | 150 } |
| 143 | 151 |
| 144 #if defined(__i386__) | 152 #if defined(__i386__) |
| 145 if (SyscallSets::IsSocketCall(sysno)) | 153 if (SyscallSets::IsSocketCall(sysno)) |
| 146 return RestrictSocketcallCommand(sandbox); | 154 return RestrictSocketcallCommand(sandbox); |
| 147 #endif | 155 #endif |
| 148 | 156 |
| 149 if (IsBaselinePolicyWatched(sysno)) { | 157 if (IsBaselinePolicyWatched(sysno)) { |
| 150 // Previously unseen syscalls. TODO(jln): some of these should | 158 // Previously unseen syscalls. TODO(jln): some of these should |
| 151 // be denied gracefully right away. | 159 // be denied gracefully right away. |
| 152 return sandbox->Trap(CrashSIGSYS_Handler, NULL); | 160 return sandbox->Trap(CrashSIGSYS_Handler, NULL); |
| 153 } | 161 } |
| 162 |
| 154 // In any other case crash the program with our SIGSYS handler. | 163 // In any other case crash the program with our SIGSYS handler. |
| 155 return sandbox->Trap(CrashSIGSYS_Handler, NULL); | 164 return sandbox->Trap(CrashSIGSYS_Handler, NULL); |
| 156 } | 165 } |
| 157 | 166 |
| 158 } // namespace. | 167 } // namespace. |
| 159 | 168 |
| 160 // Unfortunately C++03 doesn't allow delegated constructors. | 169 // Unfortunately C++03 doesn't allow delegated constructors. |
| 161 // Call other constructor when C++11 lands. | 170 // Call other constructor when C++11 lands. |
| 162 BaselinePolicy::BaselinePolicy() | 171 BaselinePolicy::BaselinePolicy() |
| 163 : fs_denied_errno_(EPERM) {} | 172 : fs_denied_errno_(EPERM), current_pid_(syscall(__NR_getpid)) {} |
| 164 | 173 |
| 165 BaselinePolicy::BaselinePolicy(int fs_denied_errno) | 174 BaselinePolicy::BaselinePolicy(int fs_denied_errno) |
| 166 : fs_denied_errno_(fs_denied_errno) {} | 175 : fs_denied_errno_(fs_denied_errno), current_pid_(syscall(__NR_getpid)) {} |
| 167 | 176 |
| 168 BaselinePolicy::~BaselinePolicy() {} | 177 BaselinePolicy::~BaselinePolicy() { |
| 178 // Make sure that this policy is created, used and destroyed by a single |
| 179 // process. |
| 180 DCHECK_EQ(syscall(__NR_getpid), current_pid_); |
| 181 } |
| 169 | 182 |
| 170 ErrorCode BaselinePolicy::EvaluateSyscall(SandboxBPF* sandbox, | 183 ErrorCode BaselinePolicy::EvaluateSyscall(SandboxBPF* sandbox, |
| 171 int sysno) const { | 184 int sysno) const { |
| 172 return EvaluateSyscallImpl(fs_denied_errno_, sandbox, sysno); | 185 // Make sure that this policy is used in the creating process. |
| 186 if (1 == sysno) { |
| 187 DCHECK_EQ(syscall(__NR_getpid), current_pid_); |
| 188 } |
| 189 return EvaluateSyscallImpl(fs_denied_errno_, current_pid_, sandbox, sysno); |
| 173 } | 190 } |
| 174 | 191 |
| 175 } // namespace sandbox. | 192 } // namespace sandbox. |
| OLD | NEW |