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

Side by Side Diff: sandbox/linux/seccomp/sigaction.cc

Issue 3225010: Pull seccomp-sandbox in via DEPS rather than using an in-tree copy... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 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/securemem.cc ('k') | sandbox/linux/seccomp/sigprocmask.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 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.
4
5 // TODO(markus): We currently instrument the restorer functions with calls to
6 // the syscallWrapper(). This prevents gdb from properly
7 // creating backtraces of code that is running in signal
8 // handlers. We might instead want to always override the
9 // restorer with a function that contains the "magic" signature
10 // but that is not executable. The SEGV handler can detect this
11 // and then invoke the appropriate restorer.
12
13 #include "debug.h"
14 #include "sandbox_impl.h"
15
16 namespace playground {
17
18 #if defined(__NR_sigaction)
19 long Sandbox::sandbox_sigaction(int signum, const void* a_, void* oa_) {
20 const SysCalls::kernel_old_sigaction* action =
21 reinterpret_cast<const SysCalls::kernel_old_sigaction*>(a_);
22 SysCalls::kernel_old_sigaction* old_action =
23 reinterpret_cast<SysCalls::kernel_old_sigaction*>(oa_);
24
25 long rc = 0;
26 long long tm;
27 Debug::syscall(&tm, __NR_sigaction, "Executing handler");
28 if (signum == SIGSEGV) {
29 if (old_action) {
30 old_action->sa_handler_ = sa_segv_.sa_handler_;
31 old_action->sa_mask = sa_segv_.sa_mask.sig[0];
32 old_action->sa_flags = sa_segv_.sa_flags;
33 old_action->sa_restorer = sa_segv_.sa_restorer;
34 }
35 if (action) {
36 sa_segv_.sa_handler_ = action->sa_handler_;
37 sa_segv_.sa_mask.sig[0] = action->sa_mask;
38 sa_segv_.sa_flags = action->sa_flags;
39 sa_segv_.sa_restorer = action->sa_restorer;
40 }
41 } else {
42 struct {
43 int sysnum;
44 long long cookie;
45 SigAction sigaction_req;
46 } __attribute__((packed)) request;
47 request.sysnum = __NR_sigaction;
48 request.cookie = cookie();
49 request.sigaction_req.sysnum = __NR_sigaction;
50 request.sigaction_req.signum = signum;
51 request.sigaction_req.action =
52 reinterpret_cast<const SysCalls::kernel_sigaction *>(action);
53 request.sigaction_req.old_action =
54 reinterpret_cast<const SysCalls::kernel_sigaction *>(old_action);
55 request.sigaction_req.sigsetsize = 8;
56
57 SysCalls sys;
58 if (write(sys, processFdPub(), &request, sizeof(request)) !=
59 sizeof(request) ||
60 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
61 die("Failed to forward sigaction() request [sandbox]");
62 }
63 }
64 Debug::elapsed(tm, __NR_sigaction);
65 return rc;
66 }
67 #endif
68
69 #if defined(__NR_rt_sigaction)
70 #define min(a,b) ({ typeof(a) a_=(a); typeof(b) b_=(b); a_ < b_ ? a_ : b_; })
71 #define max(a,b) ({ typeof(a) a_=(a); typeof(b) b_=(b); a_ > b_ ? a_ : b_; })
72
73 long Sandbox::sandbox_rt_sigaction(int signum, const void* a_, void* oa_,
74 size_t sigsetsize) {
75 const SysCalls::kernel_sigaction* action =
76 reinterpret_cast<const SysCalls::kernel_sigaction*>(a_);
77 SysCalls::kernel_sigaction* old_action =
78 reinterpret_cast<SysCalls::kernel_sigaction*>(oa_);
79
80 long rc = 0;
81 long long tm;
82 Debug::syscall(&tm, __NR_rt_sigaction, "Executing handler");
83 if (signum == SIGSEGV) {
84 size_t theirSize = offsetof(SysCalls::kernel_sigaction, sa_mask) +
85 sigsetsize;
86 if (old_action) {
87 memcpy(old_action, &sa_segv_, min(sizeof(sa_segv_), theirSize));
88 memset(old_action + 1, 0, max(0u, theirSize - sizeof(sa_segv_)));
89 }
90 if (action) {
91 memcpy(&sa_segv_, action, min(sizeof(sa_segv_), theirSize));
92 memset(&sa_segv_.sa_mask, 0, max(0u, 8 - sigsetsize));
93 }
94 } else {
95 struct {
96 int sysnum;
97 long long cookie;
98 SigAction sigaction_req;
99 } __attribute__((packed)) request;
100 request.sysnum = __NR_rt_sigaction;
101 request.cookie = cookie();
102 request.sigaction_req.sysnum = __NR_rt_sigaction;
103 request.sigaction_req.signum = signum;
104 request.sigaction_req.action = action;
105 request.sigaction_req.old_action = old_action;
106 request.sigaction_req.sigsetsize = sigsetsize;
107
108 SysCalls sys;
109 if (write(sys, processFdPub(), &request, sizeof(request)) !=
110 sizeof(request) ||
111 read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
112 die("Failed to forward rt_sigaction() request [sandbox]");
113 }
114 }
115 Debug::elapsed(tm, __NR_rt_sigaction);
116 return rc;
117 }
118 #endif
119
120 #if defined(__NR_signal)
121 void* Sandbox::sandbox_signal(int signum, const void* handler) {
122 struct kernel_old_sigaction sa, osa;
123 sa.sa_handler_ = reinterpret_cast<void (*)(int)>(handler);
124 sa.sa_flags = SA_NODEFER | SA_RESETHAND | SA_RESTORER;
125 sa.sa_mask = 0;
126 asm volatile(
127 "lea 0f, %0\n"
128 "jmp 1f\n"
129 "0:pop %%eax\n"
130 "mov $119, %%eax\n" // __NR_sigreturn
131 "int $0x80\n"
132 "1:\n"
133 : "=r"(sa.sa_restorer));
134 long rc = sandbox_sigaction(signum, &sa, &osa);
135 if (rc < 0) {
136 return (void *)rc;
137 }
138 return reinterpret_cast<void *>(osa.sa_handler_);
139 }
140 #endif
141
142 bool Sandbox::process_sigaction(int parentMapsFd, int sandboxFd,
143 int threadFdPub, int threadFd,
144 SecureMem::Args* mem) {
145 // We need to intercept sigaction() in order to properly rewrite calls to
146 // sigaction(SEGV). While there is no security implication if we didn't do
147 // so, it would end up preventing the program from running correctly as the
148 // the sandbox's SEGV handler could accidentally get removed. All of this is
149 // done in sandbox_{,rt_}sigaction(). But we still bounce through the
150 // trusted process as that is the only way we can instrument system calls.
151 // This is somewhat needlessly complicated. But as sigaction() is not a
152 // performance critical system call, it is easier to do this way than to
153 // extend the format of the syscall_table so that it could deal with this
154 // special case.
155
156 // Read request
157 SigAction sigaction_req;
158 SysCalls sys;
159 if (read(sys, sandboxFd, &sigaction_req, sizeof(sigaction_req)) !=
160 sizeof(sigaction_req)) {
161 die("Failed to read parameters for sigaction() [process]");
162 }
163 if (sigaction_req.signum == SIGSEGV) {
164 // This should never happen. Something went wrong when intercepting the
165 // system call. This is not a security problem, but it clearly doesn't
166 // make sense to let the system call pass.
167 SecureMem::abandonSystemCall(threadFd, -EINVAL);
168 return false;
169 }
170 SecureMem::sendSystemCall(threadFdPub, false, -1, mem, sigaction_req.sysnum,
171 sigaction_req.signum, sigaction_req.action,
172 sigaction_req.old_action,
173 sigaction_req.sigsetsize);
174 return true;
175 }
176
177 } // namespace
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp/securemem.cc ('k') | sandbox/linux/seccomp/sigprocmask.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698