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

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

Issue 1739011: Added support for sigreturn() and rt_sigreturn(). On x86-32, this is... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 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/library.cc ('k') | sandbox/linux/seccomp/sandbox_impl.h » ('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) 2010 The Chromium Authors. All rights reserved. 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 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 #include "library.h" 5 #include "library.h"
6 #include "sandbox_impl.h" 6 #include "sandbox_impl.h"
7 #include "syscall_table.h" 7 #include "syscall_table.h"
8 8
9 namespace playground { 9 namespace playground {
10 10
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 void Sandbox::setupSignalHandlers() { 114 void Sandbox::setupSignalHandlers() {
115 // Set SIGCHLD to SIG_DFL so that waitpid() can work 115 // Set SIGCHLD to SIG_DFL so that waitpid() can work
116 SysCalls sys; 116 SysCalls sys;
117 struct SysCalls::kernel_sigaction sa; 117 struct SysCalls::kernel_sigaction sa;
118 memset(&sa, 0, sizeof(sa)); 118 memset(&sa, 0, sizeof(sa));
119 sa.sa_handler_ = SIG_DFL; 119 sa.sa_handler_ = SIG_DFL;
120 sys.sigaction(SIGCHLD, &sa, NULL); 120 sys.sigaction(SIGCHLD, &sa, NULL);
121 121
122 // Set up SEGV handler for dealing with RDTSC instructions, system calls 122 // Set up SEGV handler for dealing with RDTSC instructions, system calls
123 // that have been rewritten to use INT0, and for sigpending() emulation. 123 // that have been rewritten to use INT0, and for sigpending() emulation.
124 sa.sa_handler_ = segv(); 124 sa.sa_sigaction_ = segv();
125 sa.sa_flags = SA_SIGINFO;
125 sys.sigaction(SIGSEGV, &sa, NULL); 126 sys.sigaction(SIGSEGV, &sa, NULL);
126 127
127 // Unblock SIGSEGV and SIGCHLD 128 // Unblock SIGSEGV and SIGCHLD
128 SysCalls::kernel_sigset_t mask; 129 SysCalls::kernel_sigset_t mask;
129 memset(&mask, 0x00, sizeof(mask)); 130 memset(&mask, 0x00, sizeof(mask));
130 mask.sig[0] |= (1 << (SIGSEGV - 1)) | (1 << (SIGCHLD - 1)); 131 mask.sig[0] |= (1 << (SIGSEGV - 1)) | (1 << (SIGCHLD - 1));
131 sys.sigprocmask(SIG_UNBLOCK, &mask, 0); 132 sys.sigprocmask(SIG_UNBLOCK, &mask, 0);
132 } 133 }
133 134
134 void (*Sandbox::segv())(int signo) { 135 void (*Sandbox::segv())(int signo, SysCalls::siginfo *context, void *unused) {
135 void (*fnc)(int signo); 136 void (*fnc)(int signo, SysCalls::siginfo *context, void *unused);
136 asm volatile( 137 asm volatile(
137 "call 999f\n" 138 "call 999f\n"
138 #if defined(__x86_64__) 139 #if defined(__x86_64__)
139 // Inspect instruction at the point where the segmentation fault 140 // Inspect instruction at the point where the segmentation fault
140 // happened. If it is RDTSC, forward the request to the trusted 141 // happened. If it is RDTSC, forward the request to the trusted
141 // thread. 142 // thread.
142 "mov $-3, %%r14\n" // request for RDTSC 143 "mov $-3, %%r14\n" // request for RDTSC
143 "mov 0xB0(%%rsp), %%r15\n" // %rip at time of segmentation fault 144 "mov 0xB0(%%rsp), %%r15\n" // %rip at time of segmentation fault
144 "cmpw $0x310F, (%%r15)\n" // RDTSC 145 "cmpw $0x310F, (%%r15)\n" // RDTSC
145 "jz 0f\n" 146 "jz 0f\n"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 "jz 7f\n" 192 "jz 7f\n"
192 "mov %%rcx, 0xA0(%%rsp)\n" // %rcx at time of segmentation fault 193 "mov %%rcx, 0xA0(%%rsp)\n" // %rcx at time of segmentation fault
193 "7:mov %%rax, 0x98(%%rsp)\n" // %rax at time of segmentation fault 194 "7:mov %%rax, 0x98(%%rsp)\n" // %rax at time of segmentation fault
194 "jmp 3b\n" 195 "jmp 3b\n"
195 196
196 // If the instruction is INT 0, then this was probably the result 197 // If the instruction is INT 0, then this was probably the result
197 // of playground::Library being unable to find a way to safely 198 // of playground::Library being unable to find a way to safely
198 // rewrite the system call instruction. Retrieve the CPU register 199 // rewrite the system call instruction. Retrieve the CPU register
199 // at the time of the segmentation fault and invoke syscallWrapper(). 200 // at the time of the segmentation fault and invoke syscallWrapper().
200 "8:cmpw $0x00CD, (%%r15)\n" // INT $0x0 201 "8:cmpw $0x00CD, (%%r15)\n" // INT $0x0
201 "jnz 14f\n" 202 "jnz 16f\n"
202 #ifndef NDEBUG 203 #ifndef NDEBUG
203 "lea 200f(%%rip), %%rdi\n" 204 "lea 200f(%%rip), %%rdi\n"
204 "call playground$debugMessage\n" 205 "call playground$debugMessage\n"
205 #endif 206 #endif
206 "mov 0x98(%%rsp), %%rax\n" // %rax at time of segmentation fault 207 "mov 0x98(%%rsp), %%rax\n" // %rax at time of segmentation fault
207 "mov 0x70(%%rsp), %%rdi\n" // %rdi at time of segmentation fault 208 "mov 0x70(%%rsp), %%rdi\n" // %rdi at time of segmentation fault
208 "mov 0x78(%%rsp), %%rsi\n" // %rsi at time of segmentation fault 209 "mov 0x78(%%rsp), %%rsi\n" // %rsi at time of segmentation fault
209 "mov 0x90(%%rsp), %%rdx\n" // %rdx at time of segmentation fault 210 "mov 0x90(%%rsp), %%rdx\n" // %rdx at time of segmentation fault
210 "mov 0x40(%%rsp), %%r10\n" // %r10 at time of segmentation fault 211 "mov 0x40(%%rsp), %%r10\n" // %r10 at time of segmentation fault
211 "mov 0x30(%%rsp), %%r8\n" // %r8 at time of segmentation fault 212 "mov 0x30(%%rsp), %%r8\n" // %r8 at time of segmentation fault
(...skipping 20 matching lines...) Expand all
232 "jmp 11f\n" 233 "jmp 11f\n"
233 "10:cmp $2, %%rdi\n" // %rdi = how (SIG_SETMASK) 234 "10:cmp $2, %%rdi\n" // %rdi = how (SIG_SETMASK)
234 "jnz 7b\n" 235 "jnz 7b\n"
235 "mov %%rsi, 0x130(%%rsp)\n" // signal mask at time of segmentation fault 236 "mov %%rsi, 0x130(%%rsp)\n" // signal mask at time of segmentation fault
236 "11:xor %%rax, %%rax\n" 237 "11:xor %%rax, %%rax\n"
237 "test %%rdx, %%rdx\n" // only return old mask, if set is non-NULL 238 "test %%rdx, %%rdx\n" // only return old mask, if set is non-NULL
238 "jz 7b\n" 239 "jz 7b\n"
239 "mov %%r10, 0(%%rdx)\n" // old_set 240 "mov %%r10, 0(%%rdx)\n" // old_set
240 "jmp 7b\n" 241 "jmp 7b\n"
241 242
243 // Handle rt_sigreturn()
244 "12:cmp $15, %%rax\n" // NR_rt_sigreturn
245 "jnz 14f\n"
246 "mov 0xA8(%%rsp), %%rsp\n" // %rsp at time of segmentation fault
247 "13:syscall\n" // rt_sigreturn() is unrestricted
248 "mov $66, %%edi\n" // rt_sigreturn() should never return
249 "mov $231, %%eax\n" // NR_exit_group
250 "jmp 13b\n"
242 251
243 // Copy signal frame onto new stack. See clone.cc for details 252 // Copy signal frame onto new stack. See clone.cc for details
244 "12:cmp $56+0xF000, %%rax\n" // NR_clone + 0xF000 253 "14:cmp $56+0xF000, %%rax\n" // NR_clone + 0xF000
245 "jnz 13f\n" 254 "jnz 15f\n"
246 "mov 0xA8(%%rsp), %%rcx\n" // %rsp at time of segmentation fault 255 "mov 0xA8(%%rsp), %%rcx\n" // %rsp at time of segmentation fault
247 "sub %%rsp, %%rcx\n" // %rcx = size of stack frame 256 "sub %%rsp, %%rcx\n" // %rcx = size of stack frame
248 "sub $8, %%rcx\n" // skip return address 257 "sub $8, %%rcx\n" // skip return address
249 "mov %%rcx, %%rax\n" // return size of signal stack frame 258 "mov %%rcx, %%rax\n" // return size of signal stack frame
250 "mov 0(%%rdx), %%rdi\n" // stack for newly clone()'d thread 259 "mov 0(%%rdx), %%rdi\n" // stack for newly clone()'d thread
251 "sub %%rcx, %%rdi\n" // copy onto new stack 260 "sub %%rcx, %%rdi\n" // copy onto new stack
252 "mov %%rdi, 0(%%rdx)\n" // allocate space on new stack 261 "mov %%rdi, 0(%%rdx)\n" // allocate space on new stack
253 "lea 8(%%rsp), %%rsi\n" // copy from current stack 262 "lea 8(%%rsp), %%rsi\n" // copy from current stack
254 "cld\n" 263 "cld\n"
255 "rep movsb\n" 264 "rep movsb\n"
256 "jmp 7b\n" 265 "jmp 7b\n"
257 266
258 // Forward system call to syscallWrapper() 267 // Forward system call to syscallWrapper()
259 "13:lea 7b(%%rip), %%rcx\n" 268 "15:lea 7b(%%rip), %%rcx\n"
260 "push %%rcx\n" 269 "push %%rcx\n"
261 "push 0xB8(%%rsp)\n" // %rip at time of segmentation fault 270 "push 0xB8(%%rsp)\n" // %rip at time of segmentation fault
262 "lea playground$syscallWrapper(%%rip), %%rcx\n" 271 "lea playground$syscallWrapper(%%rip), %%rcx\n"
263 "jmp *%%rcx\n" 272 "jmp *%%rcx\n"
264 273
265 // This was a genuine segmentation fault. Trigger the kernel's default 274 // This was a genuine segmentation fault. Trigger the kernel's default
266 // signal disposition. The only way we can do this from seccomp mode 275 // signal disposition. The only way we can do this from seccomp mode
267 // is by blocking the signal and retriggering it. 276 // is by blocking the signal and retriggering it.
268 "14:mov $2, %%edi\n" // stderr 277 "16:mov $2, %%edi\n" // stderr
269 "lea 300f(%%rip), %%rsi\n" // "Segmentation fault\n" 278 "lea 300f(%%rip), %%rsi\n" // "Segmentation fault\n"
270 "mov $301f-300f, %%edx\n" 279 "mov $301f-300f, %%edx\n"
271 "mov $1, %%eax\n" // NR_write 280 "mov $1, %%eax\n" // NR_write
272 "syscall\n" 281 "syscall\n"
273 "orb $4, 0x131(%%rsp)\n" // signal mask at time of segmentation fault 282 "orb $4, 0x131(%%rsp)\n" // signal mask at time of segmentation fault
274 "ret\n" 283 "ret\n"
275 #elif defined(__i386__) 284 #elif defined(__i386__)
276 // Inspect instruction at the point where the segmentation fault 285 // Inspect instruction at the point where the segmentation fault
277 // happened. If it is RDTSC, forward the request to the trusted 286 // happened. If it is RDTSC, forward the request to the trusted
278 // thread. 287 // thread.
279 "mov $-3, %%ebx\n" // request for RDTSC 288 "mov $-3, %%ebx\n" // request for RDTSC
280 "mov 0x40(%%esp), %%ebp\n" // %eip at time of segmentation fault 289 "mov 0xDC(%%esp), %%ebp\n" // %eip at time of segmentation fault
281 "cmpw $0x310F, (%%ebp)\n" // RDTSC 290 "cmpw $0x310F, (%%ebp)\n" // RDTSC
282 "jz 0f\n" 291 "jz 0f\n"
283 "cmpw $0x010F, (%%ebp)\n" 292 "cmpw $0x010F, (%%ebp)\n" // RDTSCP
284 "jnz 8f\n" 293 "jnz 9f\n"
285 "cmpb $0xF9, 2(%%ebp)\n" 294 "cmpb $0xF9, 2(%%ebp)\n"
286 "jnz 8f\n" 295 "jnz 9f\n"
287 "mov $-4, %%ebx\n" // request for RDTSCP 296 "mov $-4, %%ebx\n" // request for RDTSCP
288 "0:" 297 "0:"
289 #ifndef NDEBUG 298 #ifndef NDEBUG
290 "lea 100f, %%eax\n" 299 "lea 100f, %%eax\n"
291 "push %%eax\n" 300 "push %%eax\n"
292 "call playground$debugMessage\n" 301 "call playground$debugMessage\n"
293 "sub $4, %%esp\n" 302 "sub $4, %%esp\n"
294 #else 303 #else
295 "sub $8, %%esp\n" 304 "sub $8, %%esp\n" // allocate buffer for receiving timestamp
296 #endif 305 #endif
297 "push %%ebx\n" 306 "push %%ebx\n"
298 "mov %%fs:16, %%ebx\n" // fd = threadFdPub 307 "mov %%fs:16, %%ebx\n" // fd = threadFdPub
299 "mov %%esp, %%ecx\n" // buf = %esp 308 "mov %%esp, %%ecx\n" // buf = %esp
300 "mov $4, %%edx\n" // len = sizeof(int) 309 "mov $4, %%edx\n" // len = sizeof(int)
301 "1:mov %%edx, %%eax\n" // NR_write 310 "1:mov %%edx, %%eax\n" // NR_write
302 "int $0x80\n" 311 "int $0x80\n"
303 "cmp %%eax, %%edx\n" 312 "cmp %%eax, %%edx\n"
304 "jz 5f\n" 313 "jz 7f\n"
305 "cmp $-4, %%eax\n" // EINTR 314 "cmp $-4, %%eax\n" // EINTR
306 "jz 1b\n" 315 "jz 1b\n"
307 "2:add $12, %%esp\n" 316 "2:add $12, %%esp\n" // remove temporary buffer from stack
308 "movl $0, 0x34(%%esp)\n" // %eax at time of segmentation fault 317 "xor %%eax, %%eax\n"
309 "movl $0, 0x2C(%%esp)\n" // %edx at time of segmentation fault 318 "movl $0, 0xC8(%%esp)\n" // %edx at time of segmentation fault
310 "cmpw $0x310F, (%%ebp)\n" // RDTSC 319 "cmpw $0x310F, (%%ebp)\n" // RDTSC
311 "jz 3f\n" 320 "jz 3f\n"
312 "movl $0, 0x30(%%esp)\n" // %ecx at time of segmentation fault 321 "movl $0, 0xCC(%%esp)\n" // %ecx at time of segmentation fault
313 "3:addl $2, 0x40(%%esp)\n" // %eip at time of segmentation fault 322 "3:mov %%eax, 0xD0(%%esp)\n" // %eax at time of segmentation fault
314 "mov 0x40(%%esp), %%ebp\n" // %eip at time of segmentation fault 323 "4:mov 0xDC(%%esp), %%ebp\n" // %eip at time of segmentation fault
315 "cmpw $0x010F, (%%ebp)\n" // RDTSC 324 "addl $2, 0xDC(%%esp)\n" // %eip at time of segmentation fault
316 "jnz 4f\n" 325 "cmpw $0x010F, (%%ebp)\n" // RDTSCP
317 "addl $1, 0x40(%%esp)\n" // %eip at time of segmentation fault 326 "jnz 5f\n"
318 "4:ret\n" 327 "addl $1, 0xDC(%%esp)\n" // %eip at time of segmentation fault
319 "5:mov $12, %%edx\n" // len = 3*sizeof(int) 328 "5:sub $0x1C8, %%esp\n" // a legacy signal stack is much larger
320 "6:mov $3, %%eax\n" // NR_read 329 "mov 0x1CC(%%esp), %%eax\n" // push signal number
330 "push %%eax\n"
331 "lea 0x270(%%esp), %%esi\n" // copy siginfo register values
332 "lea 0x4(%%esp), %%edi\n" // into new location
333 "mov $22, %%ecx\n"
334 "cld\n"
335 "rep movsl\n"
336 "mov 0x2C8(%%esp), %%ebx\n" // copy first half of signal mask
337 "mov %%ebx, 0x54(%%esp)\n"
338 "lea 6f, %%esi\n" // copy "magic" restorer function
339 "push %%esi\n" // push restorer function
340 "lea 0x2D4(%%esp), %%edi\n" // patch up retcode magic numbers
341 "movb $2, %%cl\n"
342 "rep movsl\n"
343 "ret\n" // return to restorer function
344
345 // The restorer function is sometimes used by gdb as a magic marker to
346 // recognize signal stack frames. Don't change any of the next three
347 // instructions.
348 "6:pop %%eax\n" // remove dummy argument (signo)
349 "mov $119, %%eax\n" // NR_sigreturn
350 "int $0x80\n"
351 "7:mov $12, %%edx\n" // len = 3*sizeof(int)
352 "8:mov $3, %%eax\n" // NR_read
321 "int $0x80\n" 353 "int $0x80\n"
322 "cmp $-4, %%eax\n" // EINTR 354 "cmp $-4, %%eax\n" // EINTR
323 "jz 6b\n" 355 "jz 8b\n"
324 "cmp %%eax, %%edx\n" 356 "cmp %%eax, %%edx\n"
325 "jnz 2b\n" 357 "jnz 2b\n"
326 "pop %%eax\n" 358 "pop %%eax\n"
327 "pop %%edx\n" 359 "pop %%edx\n"
328 "pop %%ecx\n" 360 "pop %%ecx\n"
329 "mov %%edx, 0x2C(%%esp)\n" // %edx at time of segmentation fault 361 "mov %%edx, 0xC8(%%esp)\n" // %edx at time of segmentation fault
330 "cmpw $0x310F, (%%ebp)\n" // RDTSC 362 "cmpw $0x310F, (%%ebp)\n" // RDTSC
331 "jz 7f\n" 363 "jz 3b\n"
332 "mov %%ecx, 0x30(%%esp)\n" // %ecx at time of segmentation fault 364 "mov %%ecx, 0xCC(%%esp)\n" // %ecx at time of segmentation fault
333 "7:mov %%eax, 0x34(%%esp)\n" // %eax at time of segmentation fault
334 "jmp 3b\n" 365 "jmp 3b\n"
335 366
336 // If the instruction is INT 0, then this was probably the result 367 // If the instruction is INT 0, then this was probably the result
337 // of playground::Library being unable to find a way to safely 368 // of playground::Library being unable to find a way to safely
338 // rewrite the system call instruction. Retrieve the CPU register 369 // rewrite the system call instruction. Retrieve the CPU register
339 // at the time of the segmentation fault and invoke syscallWrapper(). 370 // at the time of the segmentation fault and invoke syscallWrapper().
340 "8:cmpw $0x00CD, (%%ebp)\n" // INT $0x0 371 "9:cmpw $0x00CD, (%%ebp)\n" // INT $0x0
341 "jnz 16f\n" 372 "jnz 20f\n"
342 #ifndef NDEBUG 373 #ifndef NDEBUG
343 "lea 200f, %%eax\n" 374 "lea 200f, %%eax\n"
344 "push %%eax\n" 375 "push %%eax\n"
345 "call playground$debugMessage\n" 376 "call playground$debugMessage\n"
346 "add $0x4, %%esp\n" 377 "add $0x4, %%esp\n"
347 #endif 378 #endif
348 "mov 0x34(%%esp), %%eax\n" // %eax at time of segmentation fault 379 "mov 0xD0(%%esp), %%eax\n" // %eax at time of segmentation fault
349 "mov 0x28(%%esp), %%ebx\n" // %ebx at time of segmentation fault 380 "mov 0xC4(%%esp), %%ebx\n" // %ebx at time of segmentation fault
350 "mov 0x30(%%esp), %%ecx\n" // %ecx at time of segmentation fault 381 "mov 0xCC(%%esp), %%ecx\n" // %ecx at time of segmentation fault
351 "mov 0x2C(%%esp), %%edx\n" // %edx at time of segmentation fault 382 "mov 0xC8(%%esp), %%edx\n" // %edx at time of segmentation fault
352 "mov 0x1C(%%esp), %%esi\n" // %esi at time of segmentation fault 383 "mov 0xB8(%%esp), %%esi\n" // %esi at time of segmentation fault
353 "mov 0x18(%%esp), %%edi\n" // %edi at time of segmentation fault 384 "mov 0xB4(%%esp), %%edi\n" // %edi at time of segmentation fault
354 "mov 0x20(%%esp), %%ebp\n" // %ebp at time of segmentation fault 385 "mov 0xB2(%%esp), %%ebp\n" // %ebp at time of segmentation fault
355 386
356 // Handle sigprocmask() and rt_sigprocmask() 387 // Handle sigprocmask() and rt_sigprocmask()
357 "cmp $175, %%eax\n" // NR_rt_sigprocmask 388 "cmp $175, %%eax\n" // NR_rt_sigprocmask
358 "jnz 9f\n" 389 "jnz 10f\n"
359 "mov $-22, %%eax\n" // -EINVAL 390 "mov $-22, %%eax\n" // -EINVAL
360 "cmp $8, %%esi\n" // %esi = sigsetsize (8 bytes = 64 signals) 391 "cmp $8, %%esi\n" // %esi = sigsetsize (8 bytes = 64 signals)
361 "jl 7b\n" 392 "jl 3b\n"
362 "jmp 10f\n" 393 "jmp 11f\n"
363 "9:cmp $126, %%eax\n" // NR_sigprocmask 394 "10:cmp $126, %%eax\n" // NR_sigprocmask
364 "jnz 14f\n" 395 "jnz 15f\n"
365 "mov $-22, %%eax\n" 396 "mov $-22, %%eax\n"
366 "10:mov 0x58(%%esp), %%edi\n" // signal mask at time of segmentation fault 397 "11:mov 0xFC(%%esp), %%edi\n" // signal mask at time of segmentation fault
367 "mov 0x5C(%%esp), %%ebp\n" 398 "mov 0x100(%%esp), %%ebp\n"
368 "test %%ecx, %%ecx\n" // only set mask, if set is non-NULL 399 "test %%ecx, %%ecx\n" // only set mask, if set is non-NULL
369 "jz 13f\n" 400 "jz 14f\n"
370 "mov 0(%%ecx), %%esi\n" 401 "mov 0(%%ecx), %%esi\n"
371 "mov 4(%%ecx), %%ecx\n" 402 "mov 4(%%ecx), %%ecx\n"
372 "cmp $0, %%ebx\n" // %ebx = how (SIG_BLOCK) 403 "cmp $0, %%ebx\n" // %ebx = how (SIG_BLOCK)
373 "jnz 11f\n"
374 "or %%esi, 0x58(%%esp)\n" // signal mask at time of segmentation fault
375 "or %%ecx, 0x5C(%%esp)\n"
376 "jmp 13f\n"
377 "11:cmp $1, %%ebx\n" // %ebx = how (SIG_UNBLOCK)
378 "jnz 12f\n" 404 "jnz 12f\n"
405 "or %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault
406 "or %%ecx, 0x100(%%esp)\n"
407 "jmp 14f\n"
408 "12:cmp $1, %%ebx\n" // %ebx = how (SIG_UNBLOCK)
409 "jnz 13f\n"
379 "xor $-1, %%esi\n" 410 "xor $-1, %%esi\n"
380 "xor $-1, %%ecx\n" 411 "xor $-1, %%ecx\n"
381 "and %%esi, 0x58(%%esp)\n" // signal mask at time of segmentation fault 412 "and %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault
382 "and %%ecx, 0x5C(%%esp)\n" 413 "and %%ecx, 0x100(%%esp)\n"
383 "jmp 13f\n" 414 "jmp 14f\n"
384 "12:cmp $2, %%ebx\n" // %ebx = how (SIG_SETMASK) 415 "13:cmp $2, %%ebx\n" // %ebx = how (SIG_SETMASK)
385 "jnz 7b\n" 416 "jnz 3b\n"
386 "mov %%esi, 0x58(%%esp)\n" // signal mask at time of segmentation fault 417 "mov %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault
387 "mov %%ecx, 0x5C(%%esp)\n" 418 "mov %%ecx, 0x100(%%esp)\n"
388 "13:xor %%eax, %%eax\n" 419 "14:xor %%eax, %%eax\n"
389 "test %%edx, %%edx\n" // only return old mask, if set is non-NULL 420 "test %%edx, %%edx\n" // only return old mask, if set is non-NULL
390 "jz 7b\n" 421 "jz 3b\n"
391 "mov %%edi, 0(%%edx)\n" // old_set 422 "mov %%edi, 0(%%edx)\n" // old_set
392 "mov %%ebp, 4(%%edx)\n" 423 "mov %%ebp, 4(%%edx)\n"
393 "jmp 7b\n" 424 "jmp 3b\n"
394 425
395 // Copy signal frame onto new stack. See clone.cc for details 426 // Handle sigreturn() and rt_sigreturn()
396 "14:cmp $120+0xF000, %%eax\n" // NR_clone + 0xF000 427 // See syscall.cc for a discussion on how we can emulate rt_sigreturn()
397 "jnz 15f\n" 428 // by calling sigreturn() with a suitably adjusted stack.
398 "mov 0x24(%%esp), %%ecx\n" // %esp at time of segmentation fault 429 "15:cmp $119, %%eax\n" // NR_sigreturn
399 "sub %%esp, %%ecx\n" // %ecx = size of stack frame 430 "jnz 17f\n"
400 "sub $8, %%ecx\n" // skip return address and dummy 431 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault
401 "mov %%ecx, %%eax\n" // return size of signal stack frame 432 "16:int $0x80\n" // sigreturn() is unrestricted
433 "17:cmp $173, %%eax\n" // NR_rt_sigreturn
434 "jnz 18f\n"
435 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault
436 "sub $4, %%esp\n" // add fake return address
437 "jmp 4b\n"
438
439 // Copy signal frame onto new stack. In the process, we have to convert
440 // it from an RT signal frame to a legacy signal frame.
441 // See clone.cc for details
442 "18:cmp $120+0xF000, %%eax\n" // NR_clone + 0xF000
443 "jnz 19f\n"
444 "mov 0xC0(%%esp), %%ecx\n" // %esp at time of segmentation fault
445 "sub %%esp, %%ecx\n" // %ecx = size of RT stack frame
446 "mov %%ecx, %%eax\n"
447 "add $0x1C8, %%eax\n" // adjust for size of legacy stack frame
448 "sub $0x100, %%ecx\n"
402 "mov 0(%%edx), %%edi\n" // stack for newly clone()'d thread 449 "mov 0(%%edx), %%edi\n" // stack for newly clone()'d thread
403 "sub %%ecx, %%edi\n" // copy onto new stack 450 "sub %%ecx, %%edi\n" // copy onto new stack
451 "lea 0x100(%%esp), %%esi\n"
452 "cld\n"
453 "rep movsb\n" // copy parts of RT stack(sigmask, FP state)
454 "mov 0xF0(%%esp), %%ebx\n" // adjust pointer to fpstate
455 "sub %%esi, %%ebx\n"
456 "add %%edi, %%ebx\n"
457 "sub %%eax, %%edi\n"
404 "mov %%edi, 0(%%edx)\n" // allocate space on new stack 458 "mov %%edi, 0(%%edx)\n" // allocate space on new stack
405 "lea 8(%%esp), %%esi\n" // copy from current stack 459 "lea 0xA4(%%esp), %%esi\n" // copy sigcontext from current stack
406 "cld\n" 460 "mov $0x16, %%ecx\n"
407 "rep movsb\n" 461 "rep movsl\n"
408 "jmp 7b\n" 462 "mov %%ebx, -0xC(%%edi)\n" // set pointer to fpstate
463 "mov 0xFC(%%esp), %%ebx\n" // copy first half of signal mask
464 "mov %%ebx, -0x8(%%edi)\n"
465 "mov %%eax, -0x2C(%%edi)\n" // return size of stack frame in %%eax
466 "addl $2, -0x20(%%edi)\n" // adjust %eip
467 "mov 0(%%edx), %%esp\n"
468 "mov $119, %%eax\n" // NR_sigreturn
469 "int $0x80\n"
409 470
410 // Forward system call to syscallWrapper() 471 // Forward system call to syscallWrapper()
411 "15:call playground$syscallWrapper\n" 472 "19:call playground$syscallWrapper\n"
412 "jmp 7b\n" 473 "jmp 3b\n"
413 474
414 // This was a genuine segmentation fault. Trigger the kernel's default 475 // This was a genuine segmentation fault. Trigger the kernel's default
415 // signal disposition. The only way we can do this from seccomp mode 476 // signal disposition. The only way we can do this from seccomp mode
416 // is by blocking the signal and retriggering it. 477 // is by blocking the signal and retriggering it.
417 "16:mov $2, %%ebx\n" // stderr 478 "20:mov $2, %%ebx\n" // stderr
418 "lea 300f, %%ecx\n" // "Segmentation fault\n" 479 "lea 300f, %%ecx\n" // "Segmentation fault\n"
419 "mov $301f-300f, %%edx\n" 480 "mov $301f-300f, %%edx\n"
420 "mov $4, %%eax\n" // NR_write 481 "mov $4, %%eax\n" // NR_write
421 "int $0x80\n" 482 "int $0x80\n"
422 "orb $4, 0x59(%%esp)\n" // signal mask at time of segmentation fault 483 "orb $4, 0xFD(%%esp)\n" // signal mask at time of segmentation fault
423 "ret\n" 484 "jmp 4b\n"
424 #else 485 #else
425 #error Unsupported target platform 486 #error Unsupported target platform
426 #endif 487 #endif
427 ".pushsection \".rodata\"\n" 488 ".pushsection \".rodata\"\n"
428 #ifndef NDEBUG 489 #ifndef NDEBUG
429 "100:.asciz \"RDTSC(P): Executing handler\\n\"\n" 490 "100:.asciz \"RDTSC(P): Executing handler\\n\"\n"
430 "200:.asciz \"INT $0x0: Executing handler\\n\"\n" 491 "200:.asciz \"INT $0x0: Executing handler\\n\"\n"
431 #endif 492 #endif
432 "300:.ascii \"Segmentation fault\\n\"\n" 493 "300:.ascii \"Segmentation fault\\n\"\n"
433 "301:\n" 494 "301:\n"
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 // Creating the trusted thread enables sandboxing 699 // Creating the trusted thread enables sandboxing
639 createTrustedThread(processFdPub_, cloneFdPub_, secureMem); 700 createTrustedThread(processFdPub_, cloneFdPub_, secureMem);
640 701
641 // We can no longer check for sandboxing support at this point, but we also 702 // We can no longer check for sandboxing support at this point, but we also
642 // know for a fact that it is available (as we just turned it on). So update 703 // know for a fact that it is available (as we just turned it on). So update
643 // the status to reflect this information. 704 // the status to reflect this information.
644 status_ = STATUS_ENABLED; 705 status_ = STATUS_ENABLED;
645 } 706 }
646 707
647 } // namespace 708 } // namespace
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp/library.cc ('k') | sandbox/linux/seccomp/sandbox_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698