• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
6 
7 #include <errno.h>
8 #include <sys/mman.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 
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"
20 
21 // Changing this implementation will have an effect on *all* policies.
22 // Currently this means: Renderer/Worker, GPU, Flash and NaCl.
23 
24 namespace sandbox {
25 
26 namespace {
27 
IsBaselinePolicyAllowed(int sysno)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) ||
42 #if defined(__arm__)
43          SyscallSets::IsArmPrivate(sysno) ||
44 #endif
45          SyscallSets::IsKill(sysno) ||
46          SyscallSets::IsAllowedOperationOnFd(sysno);
47 }
48 
49 // System calls that will trigger the crashing SIGSYS handler.
IsBaselinePolicyWatched(int sysno)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) ||
70 #endif
71          SyscallSets::IsNuma(sysno) ||
72          SyscallSets::IsProcessGroupOrSession(sysno) ||
73          SyscallSets::IsProcessPrivilegeChange(sysno) ||
74 #if defined(__i386__)
75          SyscallSets::IsSocketCall(sysno) ||
76 #endif
77 #if defined(__arm__)
78          SyscallSets::IsArmPciConfig(sysno) ||
79 #endif
80          SyscallSets::IsTimer(sysno);
81 }
82 
83 // |fs_denied_errno| is the errno return for denied filesystem access.
EvaluateSyscallImpl(int fs_denied_errno,SandboxBPF * sandbox,int sysno)84 ErrorCode EvaluateSyscallImpl(int fs_denied_errno, SandboxBPF* sandbox,
85                               int sysno) {
86   if (IsBaselinePolicyAllowed(sysno)) {
87     return ErrorCode(ErrorCode::ERR_ALLOWED);
88   }
89 
90 #if defined(__x86_64__) || defined(__arm__)
91   if (sysno == __NR_socketpair) {
92     // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
93     COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different);
94     return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX,
95                          ErrorCode(ErrorCode::ERR_ALLOWED),
96                          sandbox->Trap(CrashSIGSYS_Handler, NULL));
97   }
98 #endif
99 
100   if (sysno == __NR_madvise) {
101     // Only allow MADV_DONTNEED (aka MADV_FREE).
102     return sandbox->Cond(2, ErrorCode::TP_32BIT,
103                          ErrorCode::OP_EQUAL, MADV_DONTNEED,
104                          ErrorCode(ErrorCode::ERR_ALLOWED),
105                          ErrorCode(EPERM));
106   }
107 
108 #if defined(__i386__) || defined(__x86_64__)
109   if (sysno == __NR_mmap)
110     return RestrictMmapFlags(sandbox);
111 #endif
112 
113 #if defined(__i386__) || defined(__arm__)
114   if (sysno == __NR_mmap2)
115     return RestrictMmapFlags(sandbox);
116 #endif
117 
118   if (sysno == __NR_mprotect)
119     return RestrictMprotectFlags(sandbox);
120 
121   if (sysno == __NR_fcntl)
122     return RestrictFcntlCommands(sandbox);
123 
124 #if defined(__i386__) || defined(__arm__)
125   if (sysno == __NR_fcntl64)
126     return RestrictFcntlCommands(sandbox);
127 #endif
128 
129   if (SyscallSets::IsFileSystem(sysno) ||
130       SyscallSets::IsCurrentDirectory(sysno)) {
131     return ErrorCode(fs_denied_errno);
132   }
133 
134   if (SyscallSets::IsAnySystemV(sysno)) {
135     return ErrorCode(EPERM);
136   }
137 
138   if (SyscallSets::IsUmask(sysno) ||
139       SyscallSets::IsDeniedFileSystemAccessViaFd(sysno) ||
140       SyscallSets::IsDeniedGetOrModifySocket(sysno)) {
141     return ErrorCode(EPERM);
142   }
143 
144 #if defined(__i386__)
145   if (SyscallSets::IsSocketCall(sysno))
146     return RestrictSocketcallCommand(sandbox);
147 #endif
148 
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);
153   }
154   // In any other case crash the program with our SIGSYS handler.
155   return sandbox->Trap(CrashSIGSYS_Handler, NULL);
156 }
157 
158 }  // namespace.
159 
160 // Unfortunately C++03 doesn't allow delegated constructors.
161 // Call other constructor when C++11 lands.
BaselinePolicy()162 BaselinePolicy::BaselinePolicy()
163     : fs_denied_errno_(EPERM) {}
164 
BaselinePolicy(int fs_denied_errno)165 BaselinePolicy::BaselinePolicy(int fs_denied_errno)
166     : fs_denied_errno_(fs_denied_errno) {}
167 
~BaselinePolicy()168 BaselinePolicy::~BaselinePolicy() {}
169 
EvaluateSyscall(SandboxBPF * sandbox,int sysno) const170 ErrorCode BaselinePolicy::EvaluateSyscall(SandboxBPF* sandbox,
171                                           int sysno) const {
172   return EvaluateSyscallImpl(fs_denied_errno_, sandbox, sysno);
173 }
174 
175 }  // namespace sandbox.
176