OLD | NEW |
---|---|
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 <signal.h> | |
9 #include <stdint.h> | 8 #include <stdint.h> |
10 | 9 |
11 namespace playground2 { | 10 namespace playground2 { |
12 | 11 |
13 // We have to make sure that we have a single "magic" return address for | 12 // We have to make sure that we have a single "magic" return address for |
14 // our system calls, which we can check from within a BPF filter. This | 13 // our system calls, which we can check from within a BPF filter. This |
15 // works by writing a little bit of asm() code that a) enters the kernel, and | 14 // works by writing a little bit of asm() code that a) enters the kernel, and |
16 // that also b) can be invoked in a way that computes this return address. | 15 // that also b) can be invoked in a way that computes this return address. |
17 // Passing "nr" as "-1" computes the "magic" return address. Passing any | 16 // Passing "nr" as "-1" computes the "magic" return address. Passing any |
18 // other value invokes the appropriate system call. | 17 // other value invokes the appropriate system call. |
19 intptr_t SandboxSyscall(int nr, ...); | 18 intptr_t SandboxSyscall(int nr, |
19 intptr_t p0, intptr_t p1, intptr_t p2, | |
Jeffrey Yasskin
2012/12/03 22:27:35
The way StrCat() and RE2 do this is to define a cl
Markus (顧孟勤)
2012/12/04 00:54:39
Yes, that would have worked too. I don't think it
Jeffrey Yasskin
2012/12/04 01:18:48
Nope, what you have is fine with me.
On 2012/12/0
| |
20 intptr_t p3, intptr_t p4, intptr_t p5); | |
21 | |
22 | |
23 // System calls can take up to six parameters. Traditionally, glibc | |
24 // implements this property by using variadic argument lists. This works, but | |
25 // confuses modern tools such as valgrind, because we are nominally passing | |
26 // uninitialized data whenever we call through this function and pass less | |
27 // than the full six arguments. | |
28 // So, instead, we use C++'s template system to achieve a very similar | |
29 // effect. C++ automatically sets the unused parameters to zero for us, and | |
30 // it also does the correct type expansion (e.g. from 32bit to 64bit) where | |
31 // necessary. | |
32 // We have to use C-style cast operators as we want to be able to accept both | |
Jeffrey Yasskin
2012/12/03 22:27:35
You could use reinterpret_cast<intptr_t>(p0), etc.
Markus (顧孟勤)
2012/12/04 00:54:39
I am not sure, I fully understand your comment.
I
Jeffrey Yasskin
2012/12/04 01:18:48
Ah, yes, reinterpret_cast can't convert between di
| |
33 // integer and pointer types. | |
34 #if __cplusplus >= 201103 // C++11 | |
35 | |
36 template<class T0 = intptr_t, class T1 = intptr_t, class T2 = intptr_t, | |
37 class T3 = intptr_t, class T4 = intptr_t, class T5 = intptr_t> | |
38 inline intptr_t SandboxSyscall(int nr, | |
39 T0 p0 = 0, T1 p1 = 0, T2 p2 = 0, | |
40 T3 p3 = 0, T4 p4 = 0, T5 p5 = 0) | |
41 __attribute__((always_inline)); | |
Jeffrey Yasskin
2012/12/03 22:27:35
Is there a semantic reason this attribute is neede
Markus (顧孟勤)
2012/12/04 00:54:39
I'll add a comment. It is merely for the convenien
| |
42 | |
43 template<class T0, class T1, class T2, class T3, class T4, class T5> | |
44 inline intptr_t SandboxSyscall(int nr, | |
45 T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) { | |
46 return SandboxSyscall(nr, | |
47 (intptr_t)p0, (intptr_t)p1, (intptr_t)p2, | |
48 (intptr_t)p3, (intptr_t)p4, (intptr_t)p5); | |
49 } | |
50 | |
51 #else // Pre-C++11 | |
52 | |
53 // TODO(markus): C++11 has a much more concise and readable solution for | |
54 // expressing what we are doing here. Delete the fall-back code for older | |
55 // compilers as soon as we have fully switched to C++11 | |
56 | |
57 template<class T0, class T1, class T2, class T3, class T4, class T5> | |
58 inline intptr_t SandboxSyscall(int nr, | |
59 T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) | |
60 __attribute__((always_inline)); | |
61 template<class T0, class T1, class T2, class T3, class T4, class T5> | |
62 inline intptr_t SandboxSyscall(int nr, | |
63 T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) { | |
64 return SandboxSyscall(nr, | |
65 (intptr_t)p0, (intptr_t)p1, (intptr_t)p2, | |
66 (intptr_t)p3, (intptr_t)p4, (intptr_t)p5); | |
67 } | |
68 | |
69 template<class T0, class T1, class T2, class T3, class T4> | |
70 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) | |
71 __attribute__((always_inline)); | |
72 template<class T0, class T1, class T2, class T3, class T4> | |
73 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) { | |
74 return SandboxSyscall(nr, p0, p1, p2, p3, p4, 0); | |
75 } | |
76 | |
77 template<class T0, class T1, class T2, class T3> | |
78 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3) | |
79 __attribute__((always_inline)); | |
80 template<class T0, class T1, class T2, class T3> | |
81 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3) { | |
82 return SandboxSyscall(nr, p0, p1, p2, p3, 0, 0); | |
83 } | |
84 | |
85 template<class T0, class T1, class T2> | |
86 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2) | |
87 __attribute__((always_inline)); | |
88 template<class T0, class T1, class T2> | |
89 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2) { | |
90 return SandboxSyscall(nr, p0, p1, p2, 0, 0, 0); | |
91 } | |
92 | |
93 template<class T0, class T1> | |
94 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1) | |
95 __attribute__((always_inline)); | |
96 template<class T0, class T1> | |
97 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1) { | |
98 return SandboxSyscall(nr, p0, p1, 0, 0, 0, 0); | |
99 } | |
100 | |
101 template<class T0> | |
102 inline intptr_t SandboxSyscall(int nr, T0 p0) | |
103 __attribute__((always_inline)); | |
104 template<class T0> | |
105 inline intptr_t SandboxSyscall(int nr, T0 p0) { | |
106 return SandboxSyscall(nr, p0, 0, 0, 0, 0, 0); | |
107 } | |
108 | |
109 inline intptr_t SandboxSyscall(int nr) | |
110 __attribute__((always_inline)); | |
111 inline intptr_t SandboxSyscall(int nr) { | |
112 return SandboxSyscall(nr, 0, 0, 0, 0, 0, 0); | |
113 } | |
114 | |
115 #endif // Pre-C++11 | |
20 | 116 |
21 } // namespace | 117 } // namespace |
22 | 118 |
23 #endif // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__ | 119 #endif // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_H__ |
OLD | NEW |