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
3 // found in the LICENSE file.
5 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
10 #include <sys/socket.h>
12 #include "base/logging.h"
13 #include "build/build_config.h"
14 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
15 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
16 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
17 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
18 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
19 #include "sandbox/linux/services/linux_syscalls.h"
21 // Changing this implementation will have an effect on *all* policies.
22 // Currently this means: Renderer/Worker, GPU, Flash and NaCl.
28 bool IsBaselinePolicyAllowed(int sysno) {
29 return SyscallSets::IsAllowedAddressSpaceAccess(sysno) ||
30 SyscallSets::IsAllowedBasicScheduler(sysno) ||
31 SyscallSets::IsAllowedEpoll(sysno) ||
32 SyscallSets::IsAllowedFileSystemAccessViaFd(sysno) ||
33 SyscallSets::IsAllowedGeneralIo(sysno) ||
34 SyscallSets::IsAllowedGetOrModifySocket(sysno) ||
35 SyscallSets::IsAllowedGettime(sysno) ||
36 SyscallSets::IsAllowedPrctl(sysno) ||
37 SyscallSets::IsAllowedProcessStartOrDeath(sysno) ||
38 SyscallSets::IsAllowedSignalHandling(sysno) ||
39 SyscallSets::IsFutex(sysno) ||
40 SyscallSets::IsGetSimpleId(sysno) ||
41 SyscallSets::IsKernelInternalApi(sysno) ||
43 SyscallSets::IsArmPrivate(sysno) ||
45 SyscallSets::IsKill(sysno) ||
46 SyscallSets::IsAllowedOperationOnFd(sysno);
49 // System calls that will trigger the crashing SIGSYS handler.
50 bool IsBaselinePolicyWatched(int sysno) {
51 return SyscallSets::IsAdminOperation(sysno) ||
52 SyscallSets::IsAdvancedScheduler(sysno) ||
53 SyscallSets::IsAdvancedTimer(sysno) ||
54 SyscallSets::IsAsyncIo(sysno) ||
55 SyscallSets::IsDebug(sysno) ||
56 SyscallSets::IsEventFd(sysno) ||
57 SyscallSets::IsExtendedAttributes(sysno) ||
58 SyscallSets::IsFaNotify(sysno) ||
59 SyscallSets::IsFsControl(sysno) ||
60 SyscallSets::IsGlobalFSViewChange(sysno) ||
61 SyscallSets::IsGlobalProcessEnvironment(sysno) ||
62 SyscallSets::IsGlobalSystemStatus(sysno) ||
63 SyscallSets::IsInotify(sysno) ||
64 SyscallSets::IsKernelModule(sysno) ||
65 SyscallSets::IsKeyManagement(sysno) ||
66 SyscallSets::IsMessageQueue(sysno) ||
67 SyscallSets::IsMisc(sysno) ||
68 #if defined(__x86_64__)
69 SyscallSets::IsNetworkSocketInformation(sysno) ||
71 SyscallSets::IsNuma(sysno) ||
72 SyscallSets::IsProcessGroupOrSession(sysno) ||
74 SyscallSets::IsSocketCall(sysno) ||
77 SyscallSets::IsArmPciConfig(sysno) ||
79 SyscallSets::IsTimer(sysno);
82 // |fs_denied_errno| is the errno return for denied filesystem access.
83 ErrorCode EvaluateSyscallImpl(int fs_denied_errno, SandboxBPF* sandbox,
85 if (IsBaselinePolicyAllowed(sysno)) {
86 return ErrorCode(ErrorCode::ERR_ALLOWED);
89 #if defined(__x86_64__) || defined(__arm__)
90 if (sysno == __NR_socketpair) {
91 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
92 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different);
93 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX,
94 ErrorCode(ErrorCode::ERR_ALLOWED),
95 sandbox->Trap(CrashSIGSYS_Handler, NULL));
99 if (sysno == __NR_madvise) {
100 // Only allow MADV_DONTNEED (aka MADV_FREE).
101 return sandbox->Cond(2, ErrorCode::TP_32BIT,
102 ErrorCode::OP_EQUAL, MADV_DONTNEED,
103 ErrorCode(ErrorCode::ERR_ALLOWED),
107 #if defined(__i386__) || defined(__x86_64__)
108 if (sysno == __NR_mmap)
109 return RestrictMmapFlags(sandbox);
112 #if defined(__i386__) || defined(__arm__)
113 if (sysno == __NR_mmap2)
114 return RestrictMmapFlags(sandbox);
117 if (sysno == __NR_mprotect)
118 return RestrictMprotectFlags(sandbox);
120 if (sysno == __NR_fcntl)
121 return RestrictFcntlCommands(sandbox);
123 #if defined(__i386__) || defined(__arm__)
124 if (sysno == __NR_fcntl64)
125 return RestrictFcntlCommands(sandbox);
128 if (SyscallSets::IsFileSystem(sysno) ||
129 SyscallSets::IsCurrentDirectory(sysno)) {
130 return ErrorCode(fs_denied_errno);
133 if (SyscallSets::IsAnySystemV(sysno)) {
134 return ErrorCode(EPERM);
137 if (SyscallSets::IsUmask(sysno) ||
138 SyscallSets::IsDeniedFileSystemAccessViaFd(sysno) ||
139 SyscallSets::IsDeniedGetOrModifySocket(sysno) ||
140 SyscallSets::IsProcessPrivilegeChange(sysno)) {
141 return ErrorCode(EPERM);
144 #if defined(__i386__)
145 if (SyscallSets::IsSocketCall(sysno))
146 return RestrictSocketcallCommand(sandbox);
149 if (IsBaselinePolicyWatched(sysno)) {
150 // Previously unseen syscalls. TODO(jln): some of these should
151 // be denied gracefully right away.
152 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
154 // In any other case crash the program with our SIGSYS handler.
155 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
160 // Unfortunately C++03 doesn't allow delegated constructors.
161 // Call other constructor when C++11 lands.
162 BaselinePolicy::BaselinePolicy()
163 : fs_denied_errno_(EPERM) {}
165 BaselinePolicy::BaselinePolicy(int fs_denied_errno)
166 : fs_denied_errno_(fs_denied_errno) {}
168 BaselinePolicy::~BaselinePolicy() {}
170 ErrorCode BaselinePolicy::EvaluateSyscall(SandboxBPF* sandbox,
172 return EvaluateSyscallImpl(fs_denied_errno_, sandbox, sysno);
175 } // namespace sandbox.