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

Side by Side Diff: sandbox.cc

Issue 4688002: On older 32bit kernels (e.g. Ubuntu Hardy), the seccomp sandbox fails to hand... (Closed) Base URL: http://seccompsandbox.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 1 month 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 | « no previous file | no next file » | 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 "sandbox_impl.h" 5 #include "sandbox_impl.h"
6 6
7 #include "library.h" 7 #include "library.h"
8 #include "syscall_entrypoint.h" 8 #include "syscall_entrypoint.h"
9 #include "syscall_table.h" 9 #include "syscall_table.h"
10 10
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 ".popsection\n" 348 ".popsection\n"
349 #elif defined(__i386__) 349 #elif defined(__i386__)
350 // Inspect instruction at the point where the segmentation fault 350 // Inspect instruction at the point where the segmentation fault
351 // happened. If it is RDTSC, forward the request to the trusted 351 // happened. If it is RDTSC, forward the request to the trusted
352 // thread. 352 // thread.
353 "mov $-3, %%ebx\n" // request for RDTSC 353 "mov $-3, %%ebx\n" // request for RDTSC
354 "mov 0xDC(%%esp), %%ebp\n" // %eip at time of segmentation fault 354 "mov 0xDC(%%esp), %%ebp\n" // %eip at time of segmentation fault
355 "cmpw $0x310F, (%%ebp)\n" // RDTSC 355 "cmpw $0x310F, (%%ebp)\n" // RDTSC
356 "jz 0f\n" 356 "jz 0f\n"
357 "cmpw $0x010F, (%%ebp)\n" // RDTSCP 357 "cmpw $0x010F, (%%ebp)\n" // RDTSCP
358 "jnz 9f\n" 358 "jnz 10f\n"
359 "cmpb $0xF9, 2(%%ebp)\n" 359 "cmpb $0xF9, 2(%%ebp)\n"
360 "jnz 9f\n" 360 "jnz 10f\n"
361 "mov $-4, %%ebx\n" // request for RDTSCP 361 "mov $-4, %%ebx\n" // request for RDTSCP
362 "0:" 362 "0:"
363 #ifndef NDEBUG 363 #ifndef NDEBUG
364 "lea 100f, %%eax\n" 364 "lea 100f, %%eax\n"
365 "push %%eax\n" 365 "push %%eax\n"
366 "call playground$debugMessage\n" 366 "call playground$debugMessage\n"
367 "sub $4, %%esp\n" 367 "sub $4, %%esp\n"
368 #else 368 #else
369 "sub $8, %%esp\n" // allocate buffer for receiving timestamp 369 "sub $8, %%esp\n" // allocate buffer for receiving timestamp
370 #endif 370 #endif
371 "push %%ebx\n" 371 "push %%ebx\n"
372 "mov %%fs:16, %%ebx\n" // fd = threadFdPub 372 "mov %%fs:16, %%ebx\n" // fd = threadFdPub
373 "mov %%esp, %%ecx\n" // buf = %esp 373 "mov %%esp, %%ecx\n" // buf = %esp
374 "mov $4, %%edx\n" // len = sizeof(int) 374 "mov $4, %%edx\n" // len = sizeof(int)
375 "1:mov %%edx, %%eax\n" // NR_write 375 "1:mov %%edx, %%eax\n" // NR_write
376 "int $0x80\n" 376 "int $0x80\n"
377 "cmp %%eax, %%edx\n" 377 "cmp %%eax, %%edx\n"
378 "jz 7f\n" 378 "jz 8f\n"
379 "cmp $-4, %%eax\n" // EINTR 379 "cmp $-4, %%eax\n" // EINTR
380 "jz 1b\n" 380 "jz 1b\n"
381 "2:add $12, %%esp\n" // remove temporary buffer from stack 381 "2:add $12, %%esp\n" // remove temporary buffer from stack
382 "xor %%eax, %%eax\n" 382 "xor %%eax, %%eax\n"
383 "movl $0, 0xC8(%%esp)\n" // %edx at time of segmentation fault 383 "movl $0, 0xC8(%%esp)\n" // %edx at time of segmentation fault
384 "cmpw $0x310F, (%%ebp)\n" // RDTSC 384 "cmpw $0x310F, (%%ebp)\n" // RDTSC
385 "jz 3f\n" 385 "jz 3f\n"
386 "movl $0, 0xCC(%%esp)\n" // %ecx at time of segmentation fault 386 "movl $0, 0xCC(%%esp)\n" // %ecx at time of segmentation fault
387 "3:mov %%eax, 0xD0(%%esp)\n" // %eax at time of segmentation fault 387 "3:mov %%eax, 0xD0(%%esp)\n" // %eax at time of segmentation fault
388 "4:mov 0xDC(%%esp), %%ebp\n" // %eip at time of segmentation fault 388 "4:mov 0xDC(%%esp), %%ebp\n" // %eip at time of segmentation fault
389 "addl $2, 0xDC(%%esp)\n" // %eip at time of segmentation fault 389 "addl $2, 0xDC(%%esp)\n" // %eip at time of segmentation fault
390 "cmpw $0x010F, (%%ebp)\n" // RDTSCP 390 "cmpw $0x010F, (%%ebp)\n" // RDTSCP
391 "jnz 5f\n" 391 "jnz 5f\n"
392 "addl $1, 0xDC(%%esp)\n" // %eip at time of segmentation fault 392 "addl $1, 0xDC(%%esp)\n" // %eip at time of segmentation fault
393 "5:sub $0x1C8, %%esp\n" // a legacy signal stack is much larger 393 "5:add $0x4, %%esp\n"
394 "6:sub $0x1CC, %%esp\n" // a legacy signal stack is much larger
394 "mov 0x1CC(%%esp), %%eax\n" // push signal number 395 "mov 0x1CC(%%esp), %%eax\n" // push signal number
395 "push %%eax\n" 396 "push %%eax\n"
396 "lea 0x270(%%esp), %%esi\n" // copy siginfo register values 397 "lea 0x270(%%esp), %%esi\n" // copy siginfo register values
397 "lea 0x4(%%esp), %%edi\n" // into new location 398 "lea 0x4(%%esp), %%edi\n" // into new location
398 "mov $22, %%ecx\n" 399 "mov $22, %%ecx\n"
399 "cld\n" 400 "cld\n"
400 "rep movsl\n" 401 "rep movsl\n"
401 "mov 0x2C8(%%esp), %%ebx\n" // copy first half of signal mask 402 "mov 0x2C8(%%esp), %%ebx\n" // copy first half of signal mask
402 "mov %%ebx, 0x54(%%esp)\n" 403 "mov %%ebx, 0x54(%%esp)\n"
403 "lea 6f, %%esi\n" // copy "magic" restorer function 404 "7:pop %%eax\n" // remove dummy argument (signo)
404 "push %%esi\n" // push restorer function
405 "lea 0x2D4(%%esp), %%edi\n" // patch up retcode magic numbers
406 "movb $2, %%cl\n"
407 "rep movsl\n"
408 "ret\n" // return to restorer function
409
410 // The restorer function is sometimes used by gdb as a magic marker to
411 // recognize signal stack frames. Don't change any of the next three
412 // instructions.
413 "6:pop %%eax\n" // remove dummy argument (signo)
414 "mov $119, %%eax\n" // NR_sigreturn 405 "mov $119, %%eax\n" // NR_sigreturn
415 "int $0x80\n" 406 "int $0x80\n"
416 "7:mov $12, %%edx\n" // len = 3*sizeof(int) 407 "8:mov $12, %%edx\n" // len = 3*sizeof(int)
417 "8:mov $3, %%eax\n" // NR_read 408 "9:mov $3, %%eax\n" // NR_read
418 "int $0x80\n" 409 "int $0x80\n"
419 "cmp $-4, %%eax\n" // EINTR 410 "cmp $-4, %%eax\n" // EINTR
420 "jz 8b\n" 411 "jz 9b\n"
421 "cmp %%eax, %%edx\n" 412 "cmp %%eax, %%edx\n"
422 "jnz 2b\n" 413 "jnz 2b\n"
423 "pop %%eax\n" 414 "pop %%eax\n"
424 "pop %%edx\n" 415 "pop %%edx\n"
425 "pop %%ecx\n" 416 "pop %%ecx\n"
426 "mov %%edx, 0xC8(%%esp)\n" // %edx at time of segmentation fault 417 "mov %%edx, 0xC8(%%esp)\n" // %edx at time of segmentation fault
427 "cmpw $0x310F, (%%ebp)\n" // RDTSC 418 "cmpw $0x310F, (%%ebp)\n" // RDTSC
428 "jz 3b\n" 419 "jz 3b\n"
429 "mov %%ecx, 0xCC(%%esp)\n" // %ecx at time of segmentation fault 420 "mov %%ecx, 0xCC(%%esp)\n" // %ecx at time of segmentation fault
430 "jmp 3b\n" 421 "jmp 3b\n"
431 422
432 // If the instruction is INT 0, then this was probably the result 423 // If the instruction is INT 0, then this was probably the result
433 // of playground::Library being unable to find a way to safely 424 // of playground::Library being unable to find a way to safely
434 // rewrite the system call instruction. Retrieve the CPU register 425 // rewrite the system call instruction. Retrieve the CPU register
435 // at the time of the segmentation fault and invoke 426 // at the time of the segmentation fault and invoke
436 // syscallEntryPointWithFrame(). 427 // syscallEntryPointWithFrame().
437 "9:cmpw $0x00CD, (%%ebp)\n" // INT $0x0 428 "10:cmpw $0x00CD, (%%ebp)\n" // INT $0x0
438 "jnz 20f\n" 429 "jnz 20f\n"
439 #ifndef NDEBUG 430 #ifndef NDEBUG
440 "lea 200f, %%eax\n" 431 "lea 200f, %%eax\n"
441 "push %%eax\n" 432 "push %%eax\n"
442 "call playground$debugMessage\n" 433 "call playground$debugMessage\n"
443 "add $0x4, %%esp\n" 434 "add $0x4, %%esp\n"
444 #endif 435 #endif
445 "mov 0xD0(%%esp), %%eax\n" // %eax at time of segmentation fault 436 "mov 0xD0(%%esp), %%eax\n" // %eax at time of segmentation fault
446 "mov 0xC4(%%esp), %%ebx\n" // %ebx at time of segmentation fault 437 "mov 0xC4(%%esp), %%ebx\n" // %ebx at time of segmentation fault
447 "mov 0xCC(%%esp), %%ecx\n" // %ecx at time of segmentation fault 438 "mov 0xCC(%%esp), %%ecx\n" // %ecx at time of segmentation fault
448 "mov 0xC8(%%esp), %%edx\n" // %edx at time of segmentation fault 439 "mov 0xC8(%%esp), %%edx\n" // %edx at time of segmentation fault
449 "mov 0xB8(%%esp), %%esi\n" // %esi at time of segmentation fault 440 "mov 0xB8(%%esp), %%esi\n" // %esi at time of segmentation fault
450 "mov 0xB4(%%esp), %%edi\n" // %edi at time of segmentation fault 441 "mov 0xB4(%%esp), %%edi\n" // %edi at time of segmentation fault
451 "mov 0xB2(%%esp), %%ebp\n" // %ebp at time of segmentation fault 442 "mov 0xB2(%%esp), %%ebp\n" // %ebp at time of segmentation fault
452 443
453 // Handle sigprocmask() and rt_sigprocmask() 444 // Handle sigprocmask() and rt_sigprocmask()
454 "cmp $175, %%eax\n" // NR_rt_sigprocmask 445 "cmp $175, %%eax\n" // NR_rt_sigprocmask
455 "jnz 10f\n" 446 "jnz 11f\n"
456 "mov $-22, %%eax\n" // -EINVAL 447 "mov $-22, %%eax\n" // -EINVAL
457 "cmp $8, %%esi\n" // %esi = sigsetsize (8 bytes = 64 signals) 448 "cmp $8, %%esi\n" // %esi = sigsetsize (8 bytes = 64 signals)
458 "jl 3b\n" 449 "jl 3b\n"
459 "jmp 11f\n" 450 "jmp 12f\n"
460 "10:cmp $126, %%eax\n" // NR_sigprocmask 451 "11:cmp $126, %%eax\n" // NR_sigprocmask
461 "jnz 15f\n" 452 "jnz 16f\n"
462 "mov $-22, %%eax\n" 453 "mov $-22, %%eax\n"
463 "11:mov 0xFC(%%esp), %%edi\n" // signal mask at time of segmentation fault 454 "12:mov 0xFC(%%esp), %%edi\n" // signal mask at time of segmentation fault
464 "mov 0x100(%%esp), %%ebp\n" 455 "mov 0x100(%%esp), %%ebp\n"
465 "test %%ecx, %%ecx\n" // only set mask, if set is non-NULL 456 "test %%ecx, %%ecx\n" // only set mask, if set is non-NULL
466 "jz 14f\n" 457 "jz 15f\n"
467 "mov 0(%%ecx), %%esi\n" 458 "mov 0(%%ecx), %%esi\n"
468 "mov 4(%%ecx), %%ecx\n" 459 "mov 4(%%ecx), %%ecx\n"
469 "cmp $0, %%ebx\n" // %ebx = how (SIG_BLOCK) 460 "cmp $0, %%ebx\n" // %ebx = how (SIG_BLOCK)
470 "jnz 12f\n" 461 "jnz 13f\n"
471 "or %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault 462 "or %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault
472 "or %%ecx, 0x100(%%esp)\n" 463 "or %%ecx, 0x100(%%esp)\n"
473 "jmp 14f\n" 464 "jmp 15f\n"
474 "12:cmp $1, %%ebx\n" // %ebx = how (SIG_UNBLOCK) 465 "13:cmp $1, %%ebx\n" // %ebx = how (SIG_UNBLOCK)
475 "jnz 13f\n" 466 "jnz 14f\n"
476 "xor $-1, %%esi\n" 467 "xor $-1, %%esi\n"
477 "xor $-1, %%ecx\n" 468 "xor $-1, %%ecx\n"
478 "and %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault 469 "and %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault
479 "and %%ecx, 0x100(%%esp)\n" 470 "and %%ecx, 0x100(%%esp)\n"
480 "jmp 14f\n" 471 "jmp 15f\n"
481 "13:cmp $2, %%ebx\n" // %ebx = how (SIG_SETMASK) 472 "14:cmp $2, %%ebx\n" // %ebx = how (SIG_SETMASK)
482 "jnz 3b\n" 473 "jnz 3b\n"
483 "mov %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault 474 "mov %%esi, 0xFC(%%esp)\n" // signal mask at time of segmentation fault
484 "mov %%ecx, 0x100(%%esp)\n" 475 "mov %%ecx, 0x100(%%esp)\n"
485 "14:xor %%eax, %%eax\n" 476 "15:xor %%eax, %%eax\n"
486 "test %%edx, %%edx\n" // only return old mask, if set is non-NULL 477 "test %%edx, %%edx\n" // only return old mask, if set is non-NULL
487 "jz 3b\n" 478 "jz 3b\n"
488 "mov %%edi, 0(%%edx)\n" // old_set 479 "mov %%edi, 0(%%edx)\n" // old_set
489 "mov %%ebp, 4(%%edx)\n" 480 "mov %%ebp, 4(%%edx)\n"
490 "jmp 3b\n" 481 "jmp 3b\n"
491 482
492 // Handle sigreturn() and rt_sigreturn() 483 // Handle sigreturn() and rt_sigreturn()
493 // See syscall.cc for a discussion on how we can emulate rt_sigreturn() 484 // See syscall.cc for a discussion on how we can emulate rt_sigreturn()
494 // by calling sigreturn() with a suitably adjusted stack. 485 // by calling sigreturn() with a suitably adjusted stack.
495 "15:cmp $119, %%eax\n" // NR_sigreturn 486 "16:cmp $119, %%eax\n" // NR_sigreturn
496 "jnz 17f\n" 487 "jnz 17f\n"
497 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault 488 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault
498 "16:int $0x80\n" // sigreturn() is unrestricted 489 "int $0x80\n" // sigreturn() is unrestricted
499 "17:cmp $173, %%eax\n" // NR_rt_sigreturn 490 "17:cmp $173, %%eax\n" // NR_rt_sigreturn
500 "jnz 18f\n" 491 "jnz 18f\n"
501 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault 492 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault
502 "sub $4, %%esp\n" // add fake return address 493 "sub $4, %%esp\n" // add fake return address
503 "jmp 4b\n" 494 "jmp 4b\n"
504 495
505 // Copy signal frame onto new stack. In the process, we have to convert 496 // Copy signal frame onto new stack. In the process, we have to convert
506 // it from an RT signal frame to a legacy signal frame. 497 // it from an RT signal frame to a legacy signal frame.
507 // See clone.cc for details 498 // See clone.cc for details
508 "18:cmp $120+0xF000, %%eax\n" // NR_clone + 0xF000 499 "18:cmp $120+0xF000, %%eax\n" // NR_clone + 0xF000
509 "jnz 19f\n" 500 "jnz 19f\n"
510 "lea -0x1C8(%%esp), %%eax\n"// retain stack frame upon returning 501 "lea -0x1C8(%%esp), %%eax\n"// retain stack frame upon returning
511 "mov %%eax, 0xC0(%%esp)\n" // %esp at time of segmentation fault 502 "mov %%eax, 0xC0(%%esp)\n" // %esp at time of segmentation fault
512 "jmp 3b\n" 503 "jmp 3b\n"
513 504
514 // Forward system call to syscallEntryPointWithFrame() 505 // Forward system call to syscallEntryPointWithFrame()
515 "19:push $3b\n" 506 "19:push $3b\n"
516 "push 0xE0(%%esp)\n" // %eip at time of segmentation fault 507 "push 0xE0(%%esp)\n" // %eip at time of segmentation fault
517 "jmp playground$syscallEntryPointWithFrame\n" 508 "jmp playground$syscallEntryPointWithFrame\n"
518 509
510 // This was a genuine segmentation fault. Check Sandbox::sa_segv_ for
511 // what we are supposed to do.
519 // In order to implement SA_NODEFER, we have to keep track of recursive 512 // In order to implement SA_NODEFER, we have to keep track of recursive
520 // calls to SIGSEGV handlers. This means we have to increment a counter 513 // calls to SIGSEGV handlers. This means we have to increment a counter
521 // before calling the user's signal handler, and decrement it on 514 // before calling the user's signal handler, and decrement it on
522 // leaving the user's signal handler. 515 // leaving the user's signal handler.
523 // Some signal handlers look at the return address of the signal
524 // stack, and more importantly "gdb" uses the call to {,rt_}sigreturn()
525 // as a magic signature when doing stacktraces. So, we have to use
526 // a little more unusual code to regain control after the user's
527 // signal handler is done. We adjust the return address to point to
528 // non-executable memory. And when we trigger another SEGV we pop the
529 // extraneous signal frame and then call sigreturn().
530 // N.B. We currently do not correctly adjust the SEGV counter, if the 516 // N.B. We currently do not correctly adjust the SEGV counter, if the
531 // user's signal handler exits in way other than by returning (e.g. by 517 // user's signal handler exits in way other than by returning (e.g. by
532 // directly calling {,rt_}sigreturn(), or by calling siglongjmp()). 518 // directly calling {,rt_}sigreturn(), or by calling siglongjmp()).
533 "20:lea 30f, %%edi\n" // rt-style restorer function 519 // N.B. On i386, we don't have any guarantees that NX protection works.
534 "lea 31f, %%esi\n" // legacy restorer function 520 // So, we don't even attempt to fake a correct restorer function. Some
535 "cmp %%ebp, %%edi\n" // check if returning from user's handler 521 // callers might be confused by this and will need fixing for running
536 "jnz 21f\n" 522 // inside of the seccomp sandbox.
537 "decl %%fs:0x1040-0x58\n" // decrement SEGV recursion counter 523 "20:lea playground$sa_segv, %%eax\n"
538 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault
539 "jmp 29f\n"
540 "21:cmp %%ebp, %%esi\n" // check if returning from user's handler
541 "jnz 22f\n"
542 "decl %%fs:0x1040-0x58\n" // decrement SEGV recursion counter
543 "mov 0xC0(%%esp), %%esp\n" // %esp at time of segmentation fault
544 "jmp 6b\n"
545
546 // This was a genuine segmentation fault. Check Sandbox::sa_segv_ for
547 // what we are supposed to do.
548 "22:lea playground$sa_segv, %%eax\n"
549 "cmp $0, 0(%%eax)\n" // SIG_DFL 524 "cmp $0, 0(%%eax)\n" // SIG_DFL
550 "jz 23f\n" 525 "jz 21f\n"
551 "cmp $1, 0(%%eax)\n" // SIG_IGN 526 "cmp $1, 0(%%eax)\n" // SIG_IGN
552 "jnz 24f\n" // can't really ignore synchronous signals 527 "jnz 22f\n" // can't really ignore synchronous signals
553 528
554 // Trigger the kernel's default signal disposition. The only way we can 529 // Trigger the kernel's default signal disposition. The only way we can
555 // do this from seccomp mode is by blocking the signal and retriggering 530 // do this from seccomp mode is by blocking the signal and retriggering
556 // it. 531 // it.
557 "23:orb $4, 0xFD(%%esp)\n" // signal mask at time of segmentation fault 532 "21:orb $4, 0xFD(%%esp)\n" // signal mask at time of segmentation fault
558 "jmp 5b\n" 533 "jmp 5b\n"
559 534
560 // Check sa_flags: 535 // Check sa_flags:
561 // - We can ignore SA_NOCLDSTOP, SA_NOCLDWAIT, and SA_RESTART as they 536 // - We can ignore SA_NOCLDSTOP, SA_NOCLDWAIT, and SA_RESTART as they
562 // do not have any effect for SIGSEGV. 537 // do not have any effect for SIGSEGV.
563 // - We have to always register our signal handler with SA_NODEFER so 538 // - We have to always register our signal handler with SA_NODEFER so
564 // that the user's signal handler can make system calls which might 539 // that the user's signal handler can make system calls which might
565 // require additional help from our SEGV handler. 540 // require additional help from our SEGV handler.
566 // - If the user's signal handler wasn't supposed to be SA_NODEFER, then 541 // - If the user's signal handler wasn't supposed to be SA_NODEFER, then
567 // we emulate this behavior by keeping track of a recursion counter. 542 // we emulate this behavior by keeping track of a recursion counter.
568 // 543 //
569 // TODO(markus): If/when we add support for sigaltstack(), we have to 544 // TODO(markus): If/when we add support for sigaltstack(), we have to
570 // handle SA_ONSTACK. 545 // handle SA_ONSTACK.
571 "24:cmpl $0, %%fs:0x1040-0x58\n"// check if we failed inside of SEGV handler 546 "22:cmpl $0, %%fs:0x1040-0x58\n"// check if we failed inside of SEGV handler
572 "jnz 23b\n" // if so, then terminate program 547 "jnz 21b\n" // if so, then terminate program
573 "mov 0(%%eax), %%ebx\n" // sa_segv_.sa_sigaction 548 "mov 0(%%eax), %%ebx\n" // sa_segv_.sa_sigaction
574 "mov 4(%%eax), %%ecx\n" // sa_segv_.sa_flags 549 "mov 4(%%eax), %%ecx\n" // sa_segv_.sa_flags
575 "btl $31, %%ecx\n" // SA_RESETHAND 550 "btl $31, %%ecx\n" // SA_RESETHAND
576 "jnc 25f\n" 551 "jnc 23f\n"
577 "movl $0, 0(%%eax)\n" // set handler to SIG_DFL 552 "movl $0, 0(%%eax)\n" // set handler to SIG_DFL
578 "25:btl $30, %%ecx\n" // SA_NODEFER 553 "23:btl $30, %%ecx\n" // SA_NODEFER
579 "jc 28f\n" 554 "jc 26f\n"
580 "btl $2, %%ecx\n" // SA_SIGINFO 555 "btl $2, %%ecx\n" // SA_SIGINFO
581 "jnc 26f\n" 556 "jnc 24f\n"
582 "mov %%edi, 0(%%esp)\n" // trigger a SEGV on return 557 "movl $27f, 0(%%esp)\n" // trigger a SEGV on return (if NX enabled)
Mark Seaborn 2010/11/09 09:40:31 I don't understand the "(if NX enabled)" comment.
583 "incl %%fs:0x1040-0x58\n" // increment recursion counter 558 "incl %%fs:0x1040-0x58\n" // increment recursion counter
584 "jmp *%%ebx\n" // call user's signal handler 559 "jmp *%%ebx\n" // call user's signal handler
585 "26:mov %%esi, 0(%%esp)\n" 560 "24:movl $28f, 0(%%esp)\n"
586 "incl %%fs:0x1040-0x58\n" // increment recursion counter 561 "incl %%fs:0x1040-0x58\n" // increment recursion counter
587 562
588 // We always register the signal handler to give us rt-style signal 563 // We always register the signal handler to give us rt-style signal
589 // frames. But if the user asked for legacy signal frames, we must 564 // frames. But if the user asked for legacy signal frames, we must
590 // convert the signal frame prior to calling the user's signal handler. 565 // convert the signal frame prior to calling the user's signal handler.
591 "27:sub $0x1C8, %%esp\n" // a legacy signal stack is much larger 566 "25:sub $0x1C8, %%esp\n" // a legacy signal stack is much larger
592 "mov 0x1CC(%%esp), %%eax\n" // push signal number 567 "mov 0x1CC(%%esp), %%eax\n" // push signal number
593 "push %%eax\n" 568 "push %%eax\n"
594 "mov 0x1CC(%%esp), %%eax\n" // push restorer function 569 "mov 0x1CC(%%esp), %%eax\n" // push restorer function
595 "push %%eax\n" 570 "push %%eax\n"
596 "lea 0x274(%%esp), %%esi\n" // copy siginfo register values 571 "lea 0x274(%%esp), %%esi\n" // copy siginfo register values
597 "lea 0x8(%%esp), %%edi\n" // into new location 572 "lea 0x8(%%esp), %%edi\n" // into new location
598 "mov $22, %%ecx\n" 573 "mov $22, %%ecx\n"
599 "cld\n" 574 "cld\n"
600 "rep movsl\n" 575 "rep movsl\n"
601 "mov 0x2CC(%%esp), %%eax\n" // copy first half of signal mask 576 "mov 0x2CC(%%esp), %%eax\n" // copy first half of signal mask
602 "mov %%eax, 0x58(%%esp)\n" 577 "mov %%eax, 0x58(%%esp)\n"
603 "lea 31f, %%esi\n"
604 "lea 0x2D4(%%esp), %%edi\n" // patch up retcode magic numbers
605 "movb $2, %%cl\n"
606 "rep movsl\n"
607 "jmp *%%ebx\n" // call user's signal handler 578 "jmp *%%ebx\n" // call user's signal handler
608 "28:lea 6b, %%eax\n" // set appropriate restorer function 579 "26:movl $7b, 0(%%esp)\n" // set appropriate restorer function
609 "mov %%eax, 0(%%esp)\n"
610 "btl $2, %%ecx\n" // SA_SIGINFO 580 "btl $2, %%ecx\n" // SA_SIGINFO
611 "jnc 27b\n" 581 "jnc 25b\n"
612 "lea 29f, %%eax\n" 582 "movl $6b, 0(%%esp)\n" // set appropriate restorer function
Mark Seaborn 2010/11/09 09:40:31 Indentation is 1 space off
613 "mov %%eax, 0(%%esp)\n" // set appropriate restorer function
614 "jmp *%%ebx\n" // call user's signal handler 583 "jmp *%%ebx\n" // call user's signal handler
615 "29:pushl $30f\n" // emulate rt_sigreturn() 584 "27:decl %%fs:0x1040-0x58\n"
616 "jmp 5b\n" 585 "jmp 6b\n"
617 586 "28:decl %%fs:0x1040-0x58\n"
618 // Non-executable versions of the restorer function. We use these to 587 "jmp 7b\n"
619 // trigger a SEGV upon returning from the user's signal handler, giving
620 // us an ability to clean up prior to returning from the SEGV handler.
621 ".pushsection .data\n" // move code into non-executable section
622 "30:mov $173, %%eax\n" // NR_rt_sigreturn
623 "int $0x80\n" // gdb looks for this signature when doing
624 ".byte 0\n" // backtraces
625 "31:pop %%eax\n"
626 "mov $119, %%eax\n" // NR_sigreturn
627 "int $0x80\n"
628 ".popsection\n"
629 #else 588 #else
630 #error Unsupported target platform 589 #error Unsupported target platform
631 #endif 590 #endif
632 ".pushsection \".rodata\"\n" 591 ".pushsection \".rodata\"\n"
633 #ifndef NDEBUG 592 #ifndef NDEBUG
634 "100:.asciz \"RDTSC(P): Executing handler\\n\"\n" 593 "100:.asciz \"RDTSC(P): Executing handler\\n\"\n"
635 "200:.asciz \"INT $0x0: Executing handler\\n\"\n" 594 "200:.asciz \"INT $0x0: Executing handler\\n\"\n"
636 #endif 595 #endif
637 ".popsection\n" 596 ".popsection\n"
638 "999:pop %0\n" 597 "999:pop %0\n"
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 } entrypoint; 833 } entrypoint;
875 *entrypoint.get_syscall_entrypoint() = syscallEntryPointNoFrame; 834 *entrypoint.get_syscall_entrypoint() = syscallEntryPointNoFrame;
876 835
877 // We can no longer check for sandboxing support at this point, but we also 836 // We can no longer check for sandboxing support at this point, but we also
878 // know for a fact that it is available (as we just turned it on). So update 837 // know for a fact that it is available (as we just turned it on). So update
879 // the status to reflect this information. 838 // the status to reflect this information.
880 status_ = STATUS_ENABLED; 839 status_ = STATUS_ENABLED;
881 } 840 }
882 841
883 } // namespace 842 } // namespace
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698