baseline_policy.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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 24namespace sandbox { 25 26namespace { 27 28bool 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. 50bool 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. 84ErrorCode 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. 162BaselinePolicy::BaselinePolicy() 163 : fs_denied_errno_(EPERM) {} 164 165BaselinePolicy::BaselinePolicy(int fs_denied_errno) 166 : fs_denied_errno_(fs_denied_errno) {} 167 168BaselinePolicy::~BaselinePolicy() {} 169 170ErrorCode BaselinePolicy::EvaluateSyscall(SandboxBPF* sandbox, 171 int sysno) const { 172 return EvaluateSyscallImpl(fs_denied_errno_, sandbox, sysno); 173} 174 175} // namespace sandbox. 176