1f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be
3f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// found in the LICENSE file.
4f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
5f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
6f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
7f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <errno.h>
8f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <sys/mman.h>
9f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <sys/socket.h>
10f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <sys/syscall.h>
11f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <sys/types.h>
12f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <unistd.h>
13f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
14f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "base/logging.h"
15f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "build/build_config.h"
16f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
17f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
18f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
19f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
20f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
21f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/services/syscall_wrappers.h"
22f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "sandbox/linux/system_headers/linux_syscalls.h"
23f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
2424854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko#if !defined(SO_PEEK_OFF)
2524854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko#define SO_PEEK_OFF 42
2624854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko#endif
2724854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko
28f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Changing this implementation will have an effect on *all* policies.
29f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Currently this means: Renderer/Worker, GPU, Flash and NaCl.
30f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
31f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkousing sandbox::bpf_dsl::Allow;
32f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkousing sandbox::bpf_dsl::Arg;
33f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkousing sandbox::bpf_dsl::Error;
34f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkousing sandbox::bpf_dsl::If;
35f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkousing sandbox::bpf_dsl::ResultExpr;
36f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
37f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkonamespace sandbox {
38f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
39f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkonamespace {
40f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
41f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkobool IsBaselinePolicyAllowed(int sysno) {
42f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  return SyscallSets::IsAllowedAddressSpaceAccess(sysno) ||
43f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedBasicScheduler(sysno) ||
44f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedEpoll(sysno) ||
45f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedFileSystemAccessViaFd(sysno) ||
46f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedFutex(sysno) ||
47f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedGeneralIo(sysno) ||
48f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedGetOrModifySocket(sysno) ||
49f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedGettime(sysno) ||
50f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedProcessStartOrDeath(sysno) ||
51f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedSignalHandling(sysno) ||
52f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsGetSimpleId(sysno) ||
53f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsKernelInternalApi(sysno) ||
54f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__arm__)
55f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsArmPrivate(sysno) ||
56f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
57f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__mips__)
58f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsMipsPrivate(sysno) ||
59f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
60f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAllowedOperationOnFd(sysno);
61f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}
62f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
63f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// System calls that will trigger the crashing SIGSYS handler.
64f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkobool IsBaselinePolicyWatched(int sysno) {
65f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  return SyscallSets::IsAdminOperation(sysno) ||
66f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAdvancedScheduler(sysno) ||
67f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAdvancedTimer(sysno) ||
68f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsAsyncIo(sysno) ||
69f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsDebug(sysno) ||
70f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsEventFd(sysno) ||
71f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsExtendedAttributes(sysno) ||
72f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsFaNotify(sysno) ||
73f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsFsControl(sysno) ||
74f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsGlobalFSViewChange(sysno) ||
75f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsGlobalProcessEnvironment(sysno) ||
76f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsGlobalSystemStatus(sysno) ||
77f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsInotify(sysno) ||
78f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsKernelModule(sysno) ||
79f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsKeyManagement(sysno) ||
80f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsKill(sysno) ||
81f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsMessageQueue(sysno) ||
82f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsMisc(sysno) ||
83f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__x86_64__)
84f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsNetworkSocketInformation(sysno) ||
85f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
86f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsNuma(sysno) ||
87f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsPrctl(sysno) ||
88f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsProcessGroupOrSession(sysno) ||
89f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__i386__) || defined(__mips__)
90f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsSocketCall(sysno) ||
91f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
92f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__arm__)
93f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsArmPciConfig(sysno) ||
94f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
95f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__mips__)
96f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsMipsMisc(sysno) ||
97f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
98f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko         SyscallSets::IsTimer(sysno);
99f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}
100f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
101f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// |fs_denied_errno| is the errno return for denied filesystem access.
102f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoResultExpr EvaluateSyscallImpl(int fs_denied_errno,
103f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko                               pid_t current_pid,
104f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko                               int sysno) {
105f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
106f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    defined(MEMORY_SANITIZER)
107f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // TCGETS is required by the sanitizers on failure.
108f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_ioctl) {
109f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictIoctl();
110f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
111f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
112f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_sched_getaffinity) {
113f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Allow();
114f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
115f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
116f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // Used when RSS limiting is enabled in sanitizers.
117f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_getrusage) {
118f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictGetrusage();
119f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
120f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
121f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_sigaltstack) {
122f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    // Required for better stack overflow detection in ASan. Disallowed in
123f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    // non-ASan builds.
124f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Allow();
125f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
126f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif  // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||
127f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko        // defined(MEMORY_SANITIZER)
128f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
129f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (IsBaselinePolicyAllowed(sysno)) {
130f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Allow();
131f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
132f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
133f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(OS_ANDROID)
134f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // Needed for thread creation.
135f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_sigaltstack)
136f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Allow();
137f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
138f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
139f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_clock_gettime) {
140f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictClockID();
141f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
142f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
143f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_clone) {
144f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictCloneToThreadsAndEPERMFork();
145f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
146f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
147f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_fcntl)
148f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictFcntlCommands();
149f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
150f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__i386__) || defined(__arm__) || defined(__mips__)
151f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_fcntl64)
152f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictFcntlCommands();
153f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
154f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
155f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if !defined(__aarch64__)
156f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // fork() is never used as a system call (clone() is used instead), but we
157f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // have seen it in fallback code on Android.
158f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_fork) {
159f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Error(EPERM);
160f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
161f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
162f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
163f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_futex)
164f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictFutex();
165f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
166f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_set_robust_list)
167f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Error(EPERM);
168f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
169f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_getpriority || sysno ==__NR_setpriority)
170f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictGetSetpriority(current_pid);
171f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
172f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_madvise) {
173f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    // Only allow MADV_DONTNEED (aka MADV_FREE).
174f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    const Arg<int> advice(2);
175f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return If(advice == MADV_DONTNEED, Allow()).Else(Error(EPERM));
176f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
177f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
178f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
179f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    defined(__aarch64__)
180f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_mmap)
181f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictMmapFlags();
182f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
183f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
184f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__i386__) || defined(__arm__) || defined(__mips__)
185f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_mmap2)
186f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictMmapFlags();
187f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
188f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
189f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_mprotect)
190f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictMprotectFlags();
191f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
192f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_prctl)
193f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictPrctl();
194f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
195f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \
196f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    defined(__aarch64__)
197f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (sysno == __NR_socketpair) {
198f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
199f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    static_assert(AF_UNIX == PF_UNIX,
200f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko                  "af_unix and pf_unix should not be different");
201f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    const Arg<int> domain(0);
202f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return If(domain == AF_UNIX, Allow()).Else(CrashSIGSYS());
203f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
204f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
205f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
206f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (SyscallSets::IsKill(sysno)) {
207f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictKillTarget(current_pid, sysno);
208f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
209f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
210f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (SyscallSets::IsFileSystem(sysno) ||
211f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko      SyscallSets::IsCurrentDirectory(sysno)) {
212f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Error(fs_denied_errno);
213f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
214f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
215f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (SyscallSets::IsSeccomp(sysno))
216f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Error(EPERM);
217f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
218f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (SyscallSets::IsAnySystemV(sysno)) {
219f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Error(EPERM);
220f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
221f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
222f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (SyscallSets::IsUmask(sysno) ||
223f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko      SyscallSets::IsDeniedFileSystemAccessViaFd(sysno) ||
224f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko      SyscallSets::IsDeniedGetOrModifySocket(sysno) ||
225f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko      SyscallSets::IsProcessPrivilegeChange(sysno)) {
226f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return Error(EPERM);
227f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
228f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
229f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#if defined(__i386__) || defined(__mips__)
230f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (SyscallSets::IsSocketCall(sysno))
231f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return RestrictSocketcallCommand();
232f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#endif
233f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
23424854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko#if !defined(__i386__)
23524854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko  if (sysno == __NR_getsockopt || sysno ==__NR_setsockopt) {
23624854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko    // Used by Mojo EDK to catch a message pipe being sent over itself.
23724854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko    const Arg<int> level(1);
23824854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko    const Arg<int> optname(2);
23924854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko    return If(AllOf(level == SOL_SOCKET, optname == SO_PEEK_OFF), Allow())
24024854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko        .Else(CrashSIGSYS());
24124854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko  }
24224854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko#endif
24324854748fba09df2a29f0d08d558c3acea70e7a1Alex Vakulenko
244f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (IsBaselinePolicyWatched(sysno)) {
245f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    // Previously unseen syscalls. TODO(jln): some of these should
246f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    // be denied gracefully right away.
247f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    return CrashSIGSYS();
248f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
249f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
250f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // In any other case crash the program with our SIGSYS handler.
251f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  return CrashSIGSYS();
252f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}
253f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
254f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}  // namespace.
255f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
256f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Unfortunately C++03 doesn't allow delegated constructors.
257f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Call other constructor when C++11 lands.
258f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoBaselinePolicy::BaselinePolicy() : BaselinePolicy(EPERM) {}
259f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
260f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoBaselinePolicy::BaselinePolicy(int fs_denied_errno)
261f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    : fs_denied_errno_(fs_denied_errno), policy_pid_(sys_getpid()) {
262f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}
263f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
264f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoBaselinePolicy::~BaselinePolicy() {
265f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // Make sure that this policy is created, used and destroyed by a single
266f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // process.
267f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  DCHECK_EQ(sys_getpid(), policy_pid_);
268f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}
269f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
270f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoResultExpr BaselinePolicy::EvaluateSyscall(int sysno) const {
271f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // Sanity check that we're only called with valid syscall numbers.
272f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
273f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  // Make sure that this policy is used in the creating process.
274f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  if (1 == sysno) {
275f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko    DCHECK_EQ(sys_getpid(), policy_pid_);
276f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  }
277f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  return EvaluateSyscallImpl(fs_denied_errno_, policy_pid_, sysno);
278f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}
279f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
280f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoResultExpr BaselinePolicy::InvalidSyscall() const {
281f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko  return CrashSIGSYS();
282f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}
283f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko
284f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}  // namespace sandbox.
285