Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: sandbox/linux/seccomp-bpf/syscall.h

Issue 330723003: Clean-up the SandboxSyscall interface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc ('k') | sandbox/linux/seccomp-bpf/syscall.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__ 5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__
6 #define SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__ 6 #define SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/macros.h"
10 #include "sandbox/sandbox_export.h" 11 #include "sandbox/sandbox_export.h"
11 12
12 namespace sandbox { 13 namespace sandbox {
13 14
14 // We have to make sure that we have a single "magic" return address for 15 // This purely static class can be used to perform system calls with some
15 // our system calls, which we can check from within a BPF filter. This 16 // low-level control.
16 // works by writing a little bit of asm() code that a) enters the kernel, and 17 class SANDBOX_EXPORT Syscall {
17 // that also b) can be invoked in a way that computes this return address. 18 public:
18 // Passing "nr" as "-1" computes the "magic" return address. Passing any 19 // This performs system call |nr| with the arguments p0 to p5 from a constant
19 // other value invokes the appropriate system call. 20 // userland address, which is for instance observable by seccomp-bpf filters.
20 SANDBOX_EXPORT intptr_t SandboxSyscall(int nr, 21 // The constant userland address from which these system calls are made will
21 intptr_t p0, 22 // be returned if |nr| is passed as -1.
22 intptr_t p1, 23 // On error, this function will return a value between -1 and -4095 which
23 intptr_t p2, 24 // should be interpreted as -errno.
24 intptr_t p3, 25 static intptr_t Call(int nr,
25 intptr_t p4, 26 intptr_t p0,
26 intptr_t p5); 27 intptr_t p1,
28 intptr_t p2,
29 intptr_t p3,
30 intptr_t p4,
31 intptr_t p5);
27 32
28 // System calls can take up to six parameters. Traditionally, glibc 33 // System calls can take up to six parameters. Traditionally, glibc
29 // implements this property by using variadic argument lists. This works, but 34 // implements this property by using variadic argument lists. This works, but
30 // confuses modern tools such as valgrind, because we are nominally passing 35 // confuses modern tools such as valgrind, because we are nominally passing
31 // uninitialized data whenever we call through this function and pass less 36 // uninitialized data whenever we call through this function and pass less
32 // than the full six arguments. 37 // than the full six arguments.
33 // So, instead, we use C++'s template system to achieve a very similar 38 // So, instead, we use C++'s template system to achieve a very similar
34 // effect. C++ automatically sets the unused parameters to zero for us, and 39 // effect. C++ automatically sets the unused parameters to zero for us, and
35 // it also does the correct type expansion (e.g. from 32bit to 64bit) where 40 // it also does the correct type expansion (e.g. from 32bit to 64bit) where
36 // necessary. 41 // necessary.
37 // We have to use C-style cast operators as we want to be able to accept both 42 // We have to use C-style cast operators as we want to be able to accept both
38 // integer and pointer types. 43 // integer and pointer types.
39 // We explicitly mark all functions as inline. This is not necessary in 44 template <class T0, class T1, class T2, class T3, class T4, class T5>
40 // optimized builds, where the compiler automatically figures out that it 45 static inline intptr_t
41 // can inline everything. But it makes stack traces of unoptimized builds 46 Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) {
42 // easier to read as it hides implementation details. 47 return Call(nr,
43 #if __cplusplus >= 201103 // C++11 48 (intptr_t)p0,
49 (intptr_t)p1,
50 (intptr_t)p2,
51 (intptr_t)p3,
52 (intptr_t)p4,
53 (intptr_t)p5);
54 }
44 55
45 template <class T0 = intptr_t, 56 template <class T0, class T1, class T2, class T3, class T4>
46 class T1 = intptr_t, 57 static inline intptr_t Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) {
47 class T2 = intptr_t, 58 return Call(nr, p0, p1, p2, p3, p4, 0);
48 class T3 = intptr_t, 59 }
49 class T4 = intptr_t,
50 class T5 = intptr_t>
51 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr,
52 T0 p0 = 0,
53 T1 p1 = 0,
54 T2 p2 = 0,
55 T3 p3 = 0,
56 T4 p4 = 0,
57 T5 p5 = 0)
58 __attribute__((always_inline));
59 60
60 template <class T0, class T1, class T2, class T3, class T4, class T5> 61 template <class T0, class T1, class T2, class T3>
61 SANDBOX_EXPORT inline intptr_t 62 static inline intptr_t Call(int nr, T0 p0, T1 p1, T2 p2, T3 p3) {
62 SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) { 63 return Call(nr, p0, p1, p2, p3, 0, 0);
63 return SandboxSyscall(nr, 64 }
64 (intptr_t)p0,
65 (intptr_t)p1,
66 (intptr_t)p2,
67 (intptr_t)p3,
68 (intptr_t)p4,
69 (intptr_t)p5);
70 }
71 65
72 #else // Pre-C++11 66 template <class T0, class T1, class T2>
67 static inline intptr_t Call(int nr, T0 p0, T1 p1, T2 p2) {
68 return Call(nr, p0, p1, p2, 0, 0, 0);
69 }
73 70
74 // TODO(markus): C++11 has a much more concise and readable solution for 71 template <class T0, class T1>
75 // expressing what we are doing here. Delete the fall-back code for older 72 static inline intptr_t Call(int nr, T0 p0, T1 p1) {
76 // compilers as soon as we have fully switched to C++11 73 return Call(nr, p0, p1, 0, 0, 0, 0);
74 }
77 75
78 template <class T0, class T1, class T2, class T3, class T4, class T5> 76 template <class T0>
79 SANDBOX_EXPORT inline intptr_t 77 static inline intptr_t Call(int nr, T0 p0) {
80 SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) 78 return Call(nr, p0, 0, 0, 0, 0, 0);
81 __attribute__((always_inline)); 79 }
82 template <class T0, class T1, class T2, class T3, class T4, class T5>
83 SANDBOX_EXPORT inline intptr_t
84 SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) {
85 return SandboxSyscall(nr,
86 (intptr_t)p0,
87 (intptr_t)p1,
88 (intptr_t)p2,
89 (intptr_t)p3,
90 (intptr_t)p4,
91 (intptr_t)p5);
92 }
93 80
94 template <class T0, class T1, class T2, class T3, class T4> 81 static inline intptr_t Call(int nr) { return Call(nr, 0, 0, 0, 0, 0, 0); }
95 SANDBOX_EXPORT inline intptr_t
96 SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4)
97 __attribute__((always_inline));
98 template <class T0, class T1, class T2, class T3, class T4>
99 SANDBOX_EXPORT inline intptr_t
100 SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) {
101 return SandboxSyscall(nr, p0, p1, p2, p3, p4, 0);
102 }
103 82
104 template <class T0, class T1, class T2, class T3> 83 private:
105 SANDBOX_EXPORT inline intptr_t 84 DISALLOW_IMPLICIT_CONSTRUCTORS(Syscall);
106 SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3) 85 };
107 __attribute__((always_inline));
108 template <class T0, class T1, class T2, class T3>
109 SANDBOX_EXPORT inline intptr_t
110 SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3) {
111 return SandboxSyscall(nr, p0, p1, p2, p3, 0, 0);
112 }
113
114 template <class T0, class T1, class T2>
115 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2)
116 __attribute__((always_inline));
117 template <class T0, class T1, class T2>
118 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2) {
119 return SandboxSyscall(nr, p0, p1, p2, 0, 0, 0);
120 }
121
122 template <class T0, class T1>
123 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1)
124 __attribute__((always_inline));
125 template <class T0, class T1>
126 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1) {
127 return SandboxSyscall(nr, p0, p1, 0, 0, 0, 0);
128 }
129
130 template <class T0>
131 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr, T0 p0)
132 __attribute__((always_inline));
133 template <class T0>
134 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr, T0 p0) {
135 return SandboxSyscall(nr, p0, 0, 0, 0, 0, 0);
136 }
137
138 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr)
139 __attribute__((always_inline));
140 SANDBOX_EXPORT inline intptr_t SandboxSyscall(int nr) {
141 return SandboxSyscall(nr, 0, 0, 0, 0, 0, 0);
142 }
143
144 #endif // Pre-C++11
145 86
146 } // namespace sandbox 87 } // namespace sandbox
147 88
148 #endif // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__ 89 #endif // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc ('k') | sandbox/linux/seccomp-bpf/syscall.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698