Chromium Code Reviews| 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 |