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 DCHECK_EQ(syscall(__NR_getpid), current_pid_); |
Jorge Lucangeli Obes
2014/04/29 17:01:26
This will call getpid() once per syscall per compi
jln (very slow on Chromium)
2014/04/29 18:19:52
Yeah, that's why I made it a DCHECK. But you're ri
| |
186 return EvaluateSyscallImpl(fs_denied_errno_, current_pid_, sandbox, sysno); | |
173 } | 187 } |
174 | 188 |
175 } // namespace sandbox. | 189 } // namespace sandbox. |
OLD | NEW |