1 // Copyright 2014 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/services/syscall_wrappers.h"
10 #include <sys/resource.h>
11 #include <sys/syscall.h>
13 #include <sys/types.h>
16 #include "base/compiler_specific.h"
17 #include "base/logging.h"
18 #include "base/third_party/valgrind/valgrind.h"
19 #include "build/build_config.h"
20 #include "sandbox/linux/system_headers/capability.h"
21 #include "sandbox/linux/system_headers/linux_syscalls.h"
25 pid_t
sys_getpid(void) {
26 return syscall(__NR_getpid
);
29 pid_t
sys_gettid(void) {
30 return syscall(__NR_gettid
);
33 long sys_clone(unsigned long flags
,
34 decltype(nullptr) child_stack
,
37 decltype(nullptr) tls
) {
38 const bool clone_tls_used
= flags
& CLONE_SETTLS
;
39 const bool invalid_ctid
=
40 (flags
& (CLONE_CHILD_SETTID
| CLONE_CHILD_CLEARTID
)) && !ctid
;
41 const bool invalid_ptid
= (flags
& CLONE_PARENT_SETTID
) && !ptid
;
43 // We do not support CLONE_VM.
44 const bool clone_vm_used
= flags
& CLONE_VM
;
45 if (clone_tls_used
|| invalid_ctid
|| invalid_ptid
|| clone_vm_used
) {
46 RAW_LOG(FATAL
, "Invalid usage of sys_clone");
49 if (ptid
) MSAN_UNPOISON(ptid
, sizeof(*ptid
));
50 if (ctid
) MSAN_UNPOISON(ctid
, sizeof(*ctid
));
51 // See kernel/fork.c in Linux. There is different ordering of sys_clone
52 // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options.
53 #if defined(ARCH_CPU_X86_64)
54 return syscall(__NR_clone
, flags
, child_stack
, ptid
, ctid
, tls
);
55 #elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \
56 defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY)
57 // CONFIG_CLONE_BACKWARDS defined.
58 return syscall(__NR_clone
, flags
, child_stack
, ptid
, tls
, ctid
);
62 long sys_clone(unsigned long flags
) {
63 return sys_clone(flags
, nullptr, nullptr, nullptr, nullptr);
66 void sys_exit_group(int status
) {
67 syscall(__NR_exit_group
, status
);
70 int sys_seccomp(unsigned int operation
,
72 const struct sock_fprog
* args
) {
73 return syscall(__NR_seccomp
, operation
, flags
, args
);
76 int sys_prlimit64(pid_t pid
,
78 const struct rlimit64
* new_limit
,
79 struct rlimit64
* old_limit
) {
80 int res
= syscall(__NR_prlimit64
, pid
, resource
, new_limit
, old_limit
);
81 if (res
== 0 && old_limit
) MSAN_UNPOISON(old_limit
, sizeof(*old_limit
));
85 int sys_capget(cap_hdr
* hdrp
, cap_data
* datap
) {
86 int res
= syscall(__NR_capget
, hdrp
, datap
);
88 if (hdrp
) MSAN_UNPOISON(hdrp
, sizeof(*hdrp
));
89 if (datap
) MSAN_UNPOISON(datap
, sizeof(*datap
));
94 int sys_capset(cap_hdr
* hdrp
, const cap_data
* datap
) {
95 return syscall(__NR_capset
, hdrp
, datap
);
98 int sys_getresuid(uid_t
* ruid
, uid_t
* euid
, uid_t
* suid
) {
100 #if defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARMEL)
101 // On 32-bit x86 or 32-bit arm, getresuid supports 16bit values only.
102 // Use getresuid32 instead.
103 res
= syscall(__NR_getresuid32
, ruid
, euid
, suid
);
105 res
= syscall(__NR_getresuid
, ruid
, euid
, suid
);
108 if (ruid
) MSAN_UNPOISON(ruid
, sizeof(*ruid
));
109 if (euid
) MSAN_UNPOISON(euid
, sizeof(*euid
));
110 if (suid
) MSAN_UNPOISON(suid
, sizeof(*suid
));
115 int sys_getresgid(gid_t
* rgid
, gid_t
* egid
, gid_t
* sgid
) {
117 #if defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARMEL)
118 // On 32-bit x86 or 32-bit arm, getresgid supports 16bit values only.
119 // Use getresgid32 instead.
120 res
= syscall(__NR_getresgid32
, rgid
, egid
, sgid
);
122 res
= syscall(__NR_getresgid
, rgid
, egid
, sgid
);
125 if (rgid
) MSAN_UNPOISON(rgid
, sizeof(*rgid
));
126 if (egid
) MSAN_UNPOISON(egid
, sizeof(*egid
));
127 if (sgid
) MSAN_UNPOISON(sgid
, sizeof(*sgid
));
132 int sys_chroot(const char* path
) {
133 return syscall(__NR_chroot
, path
);
136 int sys_unshare(int flags
) {
137 return syscall(__NR_unshare
, flags
);
140 } // namespace sandbox