| OLD | NEW |
| 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 <asm/unistd.h> | 5 #include <asm/unistd.h> |
| 6 | 6 |
| 7 | 7 |
| 8 #define CHECK_SYSCALL_ZERO test %eax, %eax; jnz fatal_error | 8 #define CHECK_SYSCALL_ZERO test %eax, %eax; jnz fatal_error |
| 9 | 9 |
| 10 | 10 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // code (by means of sending an IPC to its trusted thread). It goes | 38 // code (by means of sending an IPC to its trusted thread). It goes |
| 39 // through the same steps of creating a signal stack frame on the | 39 // through the same steps of creating a signal stack frame on the |
| 40 // newly created thread's stacks prior to cloning. See clone.cc for | 40 // newly created thread's stacks prior to cloning. See clone.cc for |
| 41 // details. | 41 // details. |
| 42 mov $__NR_clone + 0xF000, %eax | 42 mov $__NR_clone + 0xF000, %eax |
| 43 mov %esp, %ebp | 43 mov %esp, %ebp |
| 44 int $0 // push a signal stack frame (see clone.cc) | 44 int $0 // push a signal stack frame (see clone.cc) |
| 45 movw %si, %fs | 45 movw %si, %fs |
| 46 mov %esi, 0x4(%esp) // set up %fs upon call to sigreturn() | 46 mov %esi, 0x4(%esp) // set up %fs upon call to sigreturn() |
| 47 mov %ebp, 0x1C(%esp) // pop stack upon call to sigreturn() | 47 mov %ebp, 0x1C(%esp) // pop stack upon call to sigreturn() |
| 48 lea 999f, %ebp | 48 call 0f // determine %eip for PIC addressing |
| 49 0:pop %ebp |
| 50 movd %ebp, %mm1 |
| 51 add $(_GLOBAL_OFFSET_TABLE_+(.-0b)), %ebp |
| 52 mov playground$cloneFdPub@GOT(%ebp), %ebp |
| 53 movd 0(%ebp), %mm3 |
| 54 movd %mm1, %ebp |
| 55 add $(999f-0b), %ebp |
| 49 mov %ebp, 0x38(%esp) // return address: continue in same thread | 56 mov %ebp, 0x38(%esp) // return address: continue in same thread |
| 50 mov %esp, %ebp | 57 mov %esp, %ebp |
| 51 mov $2, %ebx // how = SIG_SETMASK | 58 mov $2, %ebx // how = SIG_SETMASK |
| 52 pushl $-1 | 59 pushl $-1 |
| 53 pushl $-1 | 60 pushl $-1 |
| 54 mov %esp, %ecx // set = full mask | 61 mov %esp, %ecx // set = full mask |
| 55 xor %edx, %edx // old_set = NULL | 62 xor %edx, %edx // old_set = NULL |
| 56 mov $8, %esi // mask all 64 signals | 63 mov $8, %esi // mask all 64 signals |
| 57 mov $__NR_rt_sigprocmask, %eax | 64 mov $__NR_rt_sigprocmask, %eax |
| 58 int $0x80 | 65 int $0x80 |
| 59 CHECK_SYSCALL_ZERO | 66 CHECK_SYSCALL_ZERO |
| 60 mov $__NR_sigprocmask, %eax | 67 mov $__NR_sigprocmask, %eax |
| 61 int $0x80 | 68 int $0x80 |
| 62 CHECK_SYSCALL_ZERO | 69 CHECK_SYSCALL_ZERO |
| 63 xor %esp, %esp // invalidate the stack in all trusted code | 70 xor %esp, %esp // invalidate the stack in all trusted code |
| 64 movd %edi, %mm6 // %mm6 = args | 71 movd %edi, %mm6 // %mm6 = args |
| 65 xor %edi, %edi // initial sequence number | 72 xor %edi, %edi // initial sequence number |
| 66 movd %edi, %mm2 | 73 movd %edi, %mm2 |
| 67 jmp 20f // create trusted thread | 74 jmp 20f // create trusted thread |
| 68 | 75 |
| 69 // TODO(markus): Coalesce the read() operations by reading into a | 76 // TODO(markus): Coalesce the read() operations by reading into a |
| 70 // bigger buffer. | 77 // bigger buffer. |
| 71 | 78 |
| 72 // Parameters: | 79 // Parameters: |
| 73 // %mm0: thread's side of threadFd | 80 // %mm0: thread's side of threadFd |
| 81 // %mm1: base address used for position independent code |
| 82 // %mm3: cloneFdPub |
| 74 // %mm5: secure memory region | 83 // %mm5: secure memory region |
| 75 // the page following this one contains the scratch space | 84 // the page following this one contains the scratch space |
| 76 | 85 |
| 77 // Local variables: | 86 // Local variables: |
| 78 // %mm2: sequence number for trusted calls | 87 // %mm2: sequence number for trusted calls |
| 79 // %mm4: thread id | 88 // %mm4: thread id |
| 80 | 89 |
| 81 // Temporary variables: | 90 // Temporary variables: |
| 82 // %ebp: system call number | 91 // %ebp: system call number |
| 83 // %mm6: secure memory of previous thread | 92 // %mm6: secure memory of previous thread |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 // 0x1C: return value | 128 // 0x1C: return value |
| 120 // 0x20: RDTSCP result (%eax) | 129 // 0x20: RDTSCP result (%eax) |
| 121 // 0x24: RDTSCP result (%edx) | 130 // 0x24: RDTSCP result (%edx) |
| 122 // 0x28: RDTSCP result (%ecx) | 131 // 0x28: RDTSCP result (%ecx) |
| 123 // 0x2C: last system call (updated in syscall.cc) | 132 // 0x2C: last system call (updated in syscall.cc) |
| 124 // 0x30: number of consecutive calls to a time fnc (e.g.gettimeofday) | 133 // 0x30: number of consecutive calls to a time fnc (e.g.gettimeofday) |
| 125 // 0x34: nesting level of system calls (for debugging purposes only) | 134 // 0x34: nesting level of system calls (for debugging purposes only) |
| 126 // 0x38: signal mask | 135 // 0x38: signal mask |
| 127 // 0x40: in SEGV handler | 136 // 0x40: in SEGV handler |
| 128 | 137 |
| 129 0:xor %esp, %esp | 138 1:xor %esp, %esp |
| 130 mov $2, %eax // %mm2 = initial sequence number | 139 mov $2, %eax // %mm2 = initial sequence number |
| 131 movd %eax, %mm2 | 140 movd %eax, %mm2 |
| 132 | 141 |
| 133 // Read request from untrusted thread, or from trusted process. In | 142 // Read request from untrusted thread, or from trusted process. In |
| 134 // either case, the data that we read has to be considered untrusted. | 143 // either case, the data that we read has to be considered untrusted. |
| 135 // read(threadFd, &scratch, 4) | 144 // read(threadFd, &scratch, 4) |
| 136 1:mov $__NR_read, %eax | 145 2:mov $__NR_read, %eax |
| 137 movd %mm0, %ebx // fd = threadFd | 146 movd %mm0, %ebx // fd = threadFd |
| 138 movd %mm5, %ecx // secure_mem | 147 movd %mm5, %ecx // secure_mem |
| 139 add $0x1000, %ecx // buf = &scratch | 148 add $0x1000, %ecx // buf = &scratch |
| 140 mov $4, %edx // len = 4 | 149 mov $4, %edx // len = 4 |
| 141 2:int $0x80 | 150 3:int $0x80 |
| 142 cmp $-4, %eax // EINTR | 151 cmp $-4, %eax // EINTR |
| 143 jz 2b | 152 jz 3b |
| 144 cmp %edx, %eax | 153 cmp %edx, %eax |
| 145 jnz fatal_error | 154 jnz fatal_error |
| 146 | 155 |
| 147 // Retrieve system call number. It is crucial that we only dereference | 156 // Retrieve system call number. It is crucial that we only dereference |
| 148 // 0x1000(%mm5) exactly once. Afterwards, memory becomes untrusted and | 157 // 0x1000(%mm5) exactly once. Afterwards, memory becomes untrusted and |
| 149 // we must use the value that we have read the first time. | 158 // we must use the value that we have read the first time. |
| 150 mov 0(%ecx), %eax | 159 mov 0(%ecx), %eax |
| 151 | 160 |
| 152 // If syscall number is -1, execute an unlocked system call from the | 161 // If syscall number is -1, execute an unlocked system call from the |
| 153 // secure memory area | 162 // secure memory area |
| 154 cmp $-1, %eax | 163 cmp $-1, %eax |
| 155 jnz 5f | 164 jnz 5f |
| 156 3:movd %mm2, %ebp | 165 movd %mm2, %ebp |
| 157 cmp %ebp, 0x4-0x1000(%ecx) | 166 cmp %ebp, 0x4-0x1000(%ecx) |
| 158 jne fatal_error | 167 jne fatal_error |
| 159 cmp 0x08-0x1000(%ecx), %eax | 168 cmp 0x08-0x1000(%ecx), %eax |
| 160 jne fatal_error | 169 jne fatal_error |
| 161 mov 0x0C-0x1000(%ecx), %eax | 170 mov 0x0C-0x1000(%ecx), %eax |
| 162 mov 0x10-0x1000(%ecx), %ebx | 171 mov 0x10-0x1000(%ecx), %ebx |
| 163 mov 0x18-0x1000(%ecx), %edx | 172 mov 0x18-0x1000(%ecx), %edx |
| 164 mov 0x1C-0x1000(%ecx), %esi | 173 mov 0x1C-0x1000(%ecx), %esi |
| 165 mov 0x20-0x1000(%ecx), %edi | 174 mov 0x20-0x1000(%ecx), %edi |
| 166 mov 0x24-0x1000(%ecx), %ebp | 175 mov 0x24-0x1000(%ecx), %ebp |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 int $0x80 | 213 int $0x80 |
| 205 CHECK_SYSCALL_ZERO | 214 CHECK_SYSCALL_ZERO |
| 206 mov %ebp, 0x54(%ebx) // set most recently returned SysV shm id | 215 mov %ebp, 0x54(%ebx) // set most recently returned SysV shm id |
| 207 xor %ebx, %ebx | 216 xor %ebx, %ebx |
| 208 | 217 |
| 209 // When debugging messages are enabled, warn about expensive system | 218 // When debugging messages are enabled, warn about expensive system |
| 210 // calls | 219 // calls |
| 211 #ifndef NDEBUG | 220 #ifndef NDEBUG |
| 212 movd %mm5, %ecx | 221 movd %mm5, %ecx |
| 213 cmpw $0, 0x50(%ecx) // debug mode | 222 cmpw $0, 0x50(%ecx) // debug mode |
| 214 jz 27f | 223 jz 26f |
| 215 mov $__NR_write, %eax | 224 mov $__NR_write, %eax |
| 216 mov $2, %ebx // fd = stderr | 225 mov $2, %ebx // fd = stderr |
| 217 lea 101f, %ecx // "This is an expensive system call" | 226 movd %mm1, %ecx |
| 227 add $(101f-0b), %ecx // "This is an expensive system call" |
| 218 mov $102f-101f, %edx // len = strlen(msg) | 228 mov $102f-101f, %edx // len = strlen(msg) |
| 219 int $0x80 | 229 int $0x80 |
| 220 xor %ebx, %ebx | 230 xor %ebx, %ebx |
| 221 #endif | 231 #endif |
| 222 | 232 |
| 223 jmp 27f // exit program, no message | 233 jmp 26f // exit program, no message |
| 224 4:int $0x80 | 234 4:int $0x80 |
| 225 jmp 15f // return result | 235 jmp 15f // return result |
| 226 | 236 |
| 227 // If syscall number is -2, execute locked system call from the | 237 // If syscall number is -2, execute locked system call from the |
| 228 // secure memory area | 238 // secure memory area |
| 229 5:jg 12f | 239 5:jg 12f |
| 230 cmp $-2, %eax | 240 cmp $-2, %eax |
| 231 jnz 9f | 241 jnz 9f |
| 232 movd %mm2, %ebp | 242 movd %mm2, %ebp |
| 233 cmp %ebp, 0x4-0x1000(%ecx) | 243 cmp %ebp, 0x4-0x1000(%ecx) |
| 234 jne fatal_error | 244 jne fatal_error |
| 235 cmp %eax, 0x8-0x1000(%ecx) | 245 cmp %eax, 0x8-0x1000(%ecx) |
| 236 jne fatal_error | 246 jne fatal_error |
| 237 | 247 |
| 238 // When debugging messages are enabled, warn about expensive system | 248 // When debugging messages are enabled, warn about expensive system |
| 239 // calls | 249 // calls |
| 240 #ifndef NDEBUG | 250 #ifndef NDEBUG |
| 241 cmpw $0, 0x50-0x1000(%ecx) | 251 cmpw $0, 0x50-0x1000(%ecx) |
| 242 jz 6f // debug mode | 252 jz 6f // debug mode |
| 243 mov %ecx, %ebp | 253 mov %ecx, %ebp |
| 244 mov $__NR_write, %eax | 254 mov $__NR_write, %eax |
| 245 mov $2, %ebx // fd = stderr | 255 mov $2, %ebx // fd = stderr |
| 246 lea 101f, %ecx // "This is an expensive system call" | 256 movd %mm1, %ecx |
| 257 add $(101f-0b), %ecx // "This is an expensive system call" |
| 247 mov $102f-101f, %edx // len = strlen(msg) | 258 mov $102f-101f, %edx // len = strlen(msg) |
| 248 int $0x80 | 259 int $0x80 |
| 249 mov %ebp, %ecx | 260 mov %ebp, %ecx |
| 250 6: | 261 6: |
| 251 #endif | 262 #endif |
| 252 | 263 |
| 253 mov 0x0C-0x1000(%ecx), %eax | 264 mov 0x0C-0x1000(%ecx), %eax |
| 254 mov 0x10-0x1000(%ecx), %ebx | 265 mov 0x10-0x1000(%ecx), %ebx |
| 255 mov 0x18-0x1000(%ecx), %edx | 266 mov 0x18-0x1000(%ecx), %edx |
| 256 mov 0x1C-0x1000(%ecx), %esi | 267 mov 0x1C-0x1000(%ecx), %esi |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 cmp %edx, %eax | 354 cmp %edx, %eax |
| 344 jnz fatal_error | 355 jnz fatal_error |
| 345 mov %ebp, %eax | 356 mov %ebp, %eax |
| 346 mov 0x00(%ecx), %ebx | 357 mov 0x00(%ecx), %ebx |
| 347 mov 0x08(%ecx), %edx | 358 mov 0x08(%ecx), %edx |
| 348 mov 0x0C(%ecx), %esi | 359 mov 0x0C(%ecx), %esi |
| 349 mov 0x10(%ecx), %edi | 360 mov 0x10(%ecx), %edi |
| 350 mov 0x14(%ecx), %ebp | 361 mov 0x14(%ecx), %ebp |
| 351 mov 0x04(%ecx), %ecx | 362 mov 0x04(%ecx), %ecx |
| 352 cmp $__NR_exit_group, %eax | 363 cmp $__NR_exit_group, %eax |
| 353 jz 27f // exit program, no message | 364 jz 26f // exit program, no message |
| 354 int $0x80 | 365 int $0x80 |
| 355 | 366 |
| 356 // Return result of system call to sandboxed thread | 367 // Return result of system call to sandboxed thread |
| 357 15:movd %mm5, %ecx // secure_mem | 368 15:movd %mm5, %ecx // secure_mem |
| 358 add $0x101C, %ecx // buf = &scratch + 28 | 369 add $0x101C, %ecx // buf = &scratch + 28 |
| 359 mov %eax, (%ecx) | 370 mov %eax, (%ecx) |
| 360 mov $4, %edx // len = 4 | 371 mov $4, %edx // len = 4 |
| 361 16:movd %mm0, %ebx // fd = threadFd | 372 16:movd %mm0, %ebx // fd = threadFd |
| 362 mov $__NR_write, %eax | 373 mov $__NR_write, %eax |
| 363 17:int $0x80 | 374 17:int $0x80 |
| 364 cmp %edx, %eax | 375 cmp %edx, %eax |
| 365 jz 1b | 376 jz 2b |
| 366 cmp $-4, %eax // EINTR | 377 cmp $-4, %eax // EINTR |
| 367 jz 17b | 378 jz 17b |
| 368 jmp fatal_error | 379 jmp fatal_error |
| 369 | 380 |
| 370 // NR_exit: | 381 // NR_exit: |
| 371 // Exit trusted thread after cleaning up resources | 382 // Exit trusted thread after cleaning up resources |
| 372 18:mov %edi, %ecx // secure_mem | 383 18:mov %edi, %ecx // secure_mem |
| 373 mov 0x68(%ecx), %ebx // fd = threadFdPub | 384 mov 0x68(%ecx), %ebx // fd = threadFdPub |
| 374 mov $__NR_close, %eax | 385 mov $__NR_close, %eax |
| 375 int $0x80 | 386 int $0x80 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 mov $__NR_socketcall, %eax | 457 mov $__NR_socketcall, %eax |
| 447 mov $8, %ebx // socketpair | 458 mov $8, %ebx // socketpair |
| 448 sub $8, %ebp // sv = child_stack | 459 sub $8, %ebp // sv = child_stack |
| 449 mov %ebp, -0x04(%ebp) | 460 mov %ebp, -0x04(%ebp) |
| 450 movl $0, -0x08(%ebp) // protocol = 0 | 461 movl $0, -0x08(%ebp) // protocol = 0 |
| 451 movl $1, -0x0C(%ebp) // type = SOCK_STREAM | 462 movl $1, -0x0C(%ebp) // type = SOCK_STREAM |
| 452 movl $1, -0x10(%ebp) // domain = AF_UNIX | 463 movl $1, -0x10(%ebp) // domain = AF_UNIX |
| 453 lea -0x10(%ebp), %ecx | 464 lea -0x10(%ebp), %ecx |
| 454 int $0x80 | 465 int $0x80 |
| 455 test %eax, %eax | 466 test %eax, %eax |
| 456 jz 28f | 467 jz 27f |
| 457 | 468 |
| 458 // If things went wrong, we don't have an (easy) way of signaling | 469 // If things went wrong, we don't have an (easy) way of signaling |
| 459 // the parent. For our purposes, it is sufficient to fail with a | 470 // the parent. For our purposes, it is sufficient to fail with a |
| 460 // fatal error. | 471 // fatal error. |
| 461 jmp fatal_error | 472 jmp fatal_error |
| 462 21:xor %ecx, %ecx | 473 21:xor %ecx, %ecx |
| 463 xor %edx, %edx | 474 xor %edx, %edx |
| 464 mov $__NR_waitpid, %eax | 475 mov $__NR_waitpid, %eax |
| 465 int $0x80 | 476 int $0x80 |
| 466 cmp $-4, %eax // EINTR | 477 cmp $-4, %eax // EINTR |
| (...skipping 12 matching lines...) Expand all Loading... |
| 479 mov $1, %edx | 490 mov $1, %edx |
| 480 mov %edx, %ecx // FUTEX_WAKE | 491 mov %edx, %ecx // FUTEX_WAKE |
| 481 mov $__NR_futex, %eax | 492 mov $__NR_futex, %eax |
| 482 int $0x80 | 493 int $0x80 |
| 483 23:mov $__NR_exit, %eax | 494 23:mov $__NR_exit, %eax |
| 484 mov $1, %ebx // status = 1 | 495 mov $1, %ebx // status = 1 |
| 485 24:int $0x80 | 496 24:int $0x80 |
| 486 fatal_error: | 497 fatal_error: |
| 487 mov $__NR_write, %eax | 498 mov $__NR_write, %eax |
| 488 mov $2, %ebx // fd = stderr | 499 mov $2, %ebx // fd = stderr |
| 489 lea 100f, %ecx // "Sandbox violation detected" | 500 movd %mm1, %ecx |
| 501 add $(100f-0b), %ecx // "Sandbox violation detected" |
| 490 mov $101f-100f, %edx // len = strlen(msg) | 502 mov $101f-100f, %edx // len = strlen(msg) |
| 491 int $0x80 | 503 int $0x80 |
| 492 26:mov $1, %ebx | 504 25:mov $1, %ebx |
| 493 27:mov $__NR_exit_group, %eax | 505 26:mov $__NR_exit_group, %eax |
| 494 jmp 24b | 506 jmp 24b |
| 495 | 507 |
| 496 // The first page is mapped read-only for use as securely shared memory | 508 // The first page is mapped read-only for use as securely shared memory |
| 497 28:movd %mm6, %edi // %edi = old_shared_mem | 509 27:movd %mm6, %edi // %edi = old_shared_mem |
| 498 mov 0x44(%edi), %ebx // addr = secure_mem | 510 mov 0x44(%edi), %ebx // addr = secure_mem |
| 499 movd %ebx, %mm5 // %mm5 = secure_mem | 511 movd %ebx, %mm5 // %mm5 = secure_mem |
| 500 movd %mm2, %esi | 512 movd %mm2, %esi |
| 501 cmp %esi, 4(%edi) | 513 cmp %esi, 4(%edi) |
| 502 jne fatal_error | 514 jne fatal_error |
| 503 mov $__NR_mprotect, %eax | 515 mov $__NR_mprotect, %eax |
| 504 mov $4096, %ecx // len = 4096 | 516 mov $4096, %ecx // len = 4096 |
| 505 mov $1, %edx // prot = PROT_READ | 517 mov $1, %edx // prot = PROT_READ |
| 506 int $0x80 | 518 int $0x80 |
| 507 CHECK_SYSCALL_ZERO | 519 CHECK_SYSCALL_ZERO |
| (...skipping 12 matching lines...) Expand all Loading... |
| 520 mov 4(%ebp), %eax // threadFd (on child's stack) | 532 mov 4(%ebp), %eax // threadFd (on child's stack) |
| 521 movd %eax, %mm0 // %mm0 = threadFd | 533 movd %eax, %mm0 // %mm0 = threadFd |
| 522 mov $__NR_clone, %eax | 534 mov $__NR_clone, %eax |
| 523 mov $0x850F00, %ebx // flags = VM|FS|FILES|SIGH|THR|SYSV|UTR | 535 mov $0x850F00, %ebx // flags = VM|FS|FILES|SIGH|THR|SYSV|UTR |
| 524 mov $1, %ecx // stack = 1 | 536 mov $1, %ecx // stack = 1 |
| 525 cmp %esi, 4(%edi) | 537 cmp %esi, 4(%edi) |
| 526 jne fatal_error | 538 jne fatal_error |
| 527 int $0x80 | 539 int $0x80 |
| 528 test %eax, %eax | 540 test %eax, %eax |
| 529 js fatal_error | 541 js fatal_error |
| 530 jz 0b // invoke trustedThreadFnc() | 542 jz 1b // invoke trustedThreadFnc() |
| 531 | 543 |
| 532 // Set up thread local storage | 544 // Set up thread local storage |
| 533 mov $0x51, %eax // seg_32bit, limit_in_pages, useable | 545 mov $0x51, %eax // seg_32bit, limit_in_pages, useable |
| 534 mov %eax, -0x04(%ebp) | 546 mov %eax, -0x04(%ebp) |
| 535 mov $0xFFFFF, %eax // limit | 547 mov $0xFFFFF, %eax // limit |
| 536 mov %eax, -0x08(%ebp) | 548 mov %eax, -0x08(%ebp) |
| 537 movd %mm5, %eax | 549 movd %mm5, %eax |
| 538 add $0x58, %eax | 550 add $0x58, %eax |
| 539 mov %eax, -0x0C(%ebp) // base_addr = &secure_mem.TLS | 551 mov %eax, -0x0C(%ebp) // base_addr = &secure_mem.TLS |
| 540 mov %fs, %eax | 552 mov %fs, %eax |
| (...skipping 22 matching lines...) Expand all Loading... |
| 563 | 575 |
| 564 // Nascent thread launches a helper that doesn't share any of our | 576 // Nascent thread launches a helper that doesn't share any of our |
| 565 // resources, except for pages mapped as MAP_SHARED. | 577 // resources, except for pages mapped as MAP_SHARED. |
| 566 // clone(SIGCHLD, stack=1) | 578 // clone(SIGCHLD, stack=1) |
| 567 mov $__NR_clone, %eax | 579 mov $__NR_clone, %eax |
| 568 mov $17, %ebx // flags = SIGCHLD | 580 mov $17, %ebx // flags = SIGCHLD |
| 569 mov $1, %ecx // stack = 1 | 581 mov $1, %ecx // stack = 1 |
| 570 int $0x80 | 582 int $0x80 |
| 571 test %eax, %eax | 583 test %eax, %eax |
| 572 js fatal_error | 584 js fatal_error |
| 573 jne 31f | 585 jne 28f |
| 574 | 586 |
| 575 // Use sendmsg() to send to the trusted process the file handles for | 587 // Use sendmsg() to send to the trusted process the file handles for |
| 576 // communicating with the new trusted thread. We also send the address | 588 // communicating with the new trusted thread. We also send the address |
| 577 // of the secure memory area (for sanity checks) and the thread id. | 589 // of the secure memory area (for sanity checks) and the thread id. |
| 578 cmp %edx, 4(%edi) | 590 cmp %edx, 4(%edi) |
| 579 jne fatal_error | 591 jne fatal_error |
| 580 | 592 |
| 581 // 0x00 socketcall: | 593 // 0x00 socketcall: |
| 582 // 0x00 socket (cloneFdPub) | 594 // 0x00 socket (cloneFdPub) |
| 583 // 0x04 msg (%ecx + 0x0C) | 595 // 0x04 msg (%ecx + 0x0C) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 597 // 0x34 iov: | 609 // 0x34 iov: |
| 598 // 0x34 iov_base (%ecx + 0x24) | 610 // 0x34 iov_base (%ecx + 0x24) |
| 599 // 0x38 iov_len ($0x10) | 611 // 0x38 iov_len ($0x10) |
| 600 // 0x3C cmsg: | 612 // 0x3C cmsg: |
| 601 // 0x3C cmsg_len ($0x14) | 613 // 0x3C cmsg_len ($0x14) |
| 602 // 0x40 cmsg_level ($1, SOL_SOCKET) | 614 // 0x40 cmsg_level ($1, SOL_SOCKET) |
| 603 // 0x44 cmsg_type ($1, SCM_RIGHTS) | 615 // 0x44 cmsg_type ($1, SCM_RIGHTS) |
| 604 // 0x48 threadFdPub (%esi) | 616 // 0x48 threadFdPub (%esi) |
| 605 // 0x4C threadFd (%mm0) | 617 // 0x4C threadFd (%mm0) |
| 606 // 0x50 | 618 // 0x50 |
| 607 lea sendmsg_data, %ecx | 619 movd %mm1, %ecx |
| 620 add $(sendmsg_data-0b), %ecx |
| 608 xor %eax, %eax | 621 xor %eax, %eax |
| 609 mov %eax, 0x08(%ecx) // flags | 622 mov %eax, 0x08(%ecx) // flags |
| 610 mov %eax, 0x0C(%ecx) // msg_name | 623 mov %eax, 0x0C(%ecx) // msg_name |
| 611 mov %eax, 0x10(%ecx) // msg_namelen | 624 mov %eax, 0x10(%ecx) // msg_namelen |
| 612 mov %eax, 0x24(%ecx) // msg_flags | 625 mov %eax, 0x24(%ecx) // msg_flags |
| 613 inc %eax | 626 inc %eax |
| 614 mov %eax, 0x18(%ecx) // msg_iovlen | 627 mov %eax, 0x18(%ecx) // msg_iovlen |
| 615 mov %eax, 0x40(%ecx) // cmsg_level | 628 mov %eax, 0x40(%ecx) // cmsg_level |
| 616 mov %eax, 0x44(%ecx) // cmsg_type | 629 mov %eax, 0x44(%ecx) // cmsg_type |
| 617 movl $0x10, 0x38(%ecx) // iov_len | 630 movl $0x10, 0x38(%ecx) // iov_len |
| 618 mov $0x14, %eax | 631 mov $0x14, %eax |
| 619 mov %eax, 0x20(%ecx) // msg_controllen | 632 mov %eax, 0x20(%ecx) // msg_controllen |
| 620 mov %eax, 0x3C(%ecx) // cmsg_len | 633 mov %eax, 0x3C(%ecx) // cmsg_len |
| 621 mov playground$cloneFdPub, %eax // cloneFdPub | 634 movd %mm3, %eax // cloneFdPub |
| 622 mov %eax, 0x00(%ecx) // socket | 635 mov %eax, 0x00(%ecx) // socket |
| 623 lea 0x0C(%ecx), %eax | 636 lea 0x0C(%ecx), %eax |
| 624 mov %eax, 0x04(%ecx) // msg | 637 mov %eax, 0x04(%ecx) // msg |
| 625 add $0x18, %eax | 638 add $0x18, %eax |
| 626 mov %eax, 0x34(%ecx) // iov_base | 639 mov %eax, 0x34(%ecx) // iov_base |
| 627 add $0x10, %eax | 640 add $0x10, %eax |
| 628 mov %eax, 0x14(%ecx) // msg_iov | 641 mov %eax, 0x14(%ecx) // msg_iov |
| 629 add $8, %eax | 642 add $8, %eax |
| 630 mov %eax, 0x1C(%ecx) // msg_control | 643 mov %eax, 0x1C(%ecx) // msg_control |
| 631 mov %esi, 0x30(%ecx) // threadFdPub | 644 mov %esi, 0x30(%ecx) // threadFdPub |
| 632 mov %esi, 0x48(%ecx) // threadFdPub | 645 mov %esi, 0x48(%ecx) // threadFdPub |
| 633 movd %mm5, %eax | 646 movd %mm5, %eax |
| 634 mov %eax, 0x28(%ecx) // secure_mem | 647 mov %eax, 0x28(%ecx) // secure_mem |
| 635 movd %mm4, %eax | 648 movd %mm4, %eax |
| 636 mov %eax, 0x2C(%ecx) // threadId | 649 mov %eax, 0x2C(%ecx) // threadId |
| 637 movd %mm0, %eax | 650 movd %mm0, %eax |
| 638 mov %eax, 0x4C(%ecx) // threadFd | 651 mov %eax, 0x4C(%ecx) // threadFd |
| 639 mov $16, %ebx // sendmsg() | 652 mov $16, %ebx // sendmsg() |
| 640 mov $__NR_socketcall, %eax | 653 mov $__NR_socketcall, %eax |
| 641 int $0x80 | 654 int $0x80 |
| 642 30:xor %ebx, %ebx | 655 xor %ebx, %ebx |
| 643 jmp 27b // exit process (no error message) | 656 jmp 26b // exit process (no error message) |
| 644 | 657 |
| 645 // Reap helper | 658 // Reap helper |
| 646 31:mov %eax, %ebx | 659 28:mov %eax, %ebx |
| 647 32:lea -4(%ebp), %ecx | 660 29:lea -4(%ebp), %ecx |
| 648 xor %edx, %edx | 661 xor %edx, %edx |
| 649 mov $__NR_waitpid, %eax | 662 mov $__NR_waitpid, %eax |
| 650 int $0x80 | 663 int $0x80 |
| 651 cmp $-4, %eax // EINTR | 664 cmp $-4, %eax // EINTR |
| 652 jz 32b | 665 jz 29b |
| 653 mov -4(%ebp), %eax | 666 mov -4(%ebp), %eax |
| 654 test %eax, %eax | 667 test %eax, %eax |
| 655 jnz 26b // exit process (no error message) | 668 jnz 25b // exit process (no error message) |
| 656 | 669 |
| 657 // Release privileges by entering seccomp mode. | 670 // Release privileges by entering seccomp mode. |
| 658 33:mov $__NR_prctl, %eax | 671 mov $__NR_prctl, %eax |
| 659 mov $22, %ebx // PR_SET_SECCOMP | 672 mov $22, %ebx // PR_SET_SECCOMP |
| 660 mov $1, %ecx | 673 mov $1, %ecx |
| 661 int $0x80 | 674 int $0x80 |
| 662 CHECK_SYSCALL_ZERO | 675 CHECK_SYSCALL_ZERO |
| 663 | 676 |
| 664 // We can finally start using the stack. Signal handlers no longer pose | 677 // We can finally start using the stack. Signal handlers no longer pose |
| 665 // a threat to us. | 678 // a threat to us. |
| 666 mov %ebp, %esp | 679 mov %ebp, %esp |
| 667 | 680 |
| 668 // Back in the newly created sandboxed thread, wait for trusted process | 681 // Back in the newly created sandboxed thread, wait for trusted process |
| 669 // to receive request. It is possible for an attacker to make us | 682 // to receive request. It is possible for an attacker to make us |
| 670 // continue even before the trusted process is done. This is OK. It'll | 683 // continue even before the trusted process is done. This is OK. It'll |
| 671 // result in us putting stale values into the new thread's TLS. But | 684 // result in us putting stale values into the new thread's TLS. But |
| 672 // that data is considered untrusted anyway. | 685 // that data is considered untrusted anyway. |
| 673 push %eax | 686 push %eax |
| 674 mov $1, %edx // len = 1 | 687 mov $1, %edx // len = 1 |
| 675 mov %esp, %ecx // buf = %esp | 688 mov %esp, %ecx // buf = %esp |
| 676 mov %esi, %ebx // fd = threadFdPub | 689 mov %esi, %ebx // fd = threadFdPub |
| 677 34:mov $__NR_read, %eax | 690 30:mov $__NR_read, %eax |
| 678 int $0x80 | 691 int $0x80 |
| 679 cmp $-4, %eax // EINTR | 692 cmp $-4, %eax // EINTR |
| 680 jz 34b | 693 jz 30b |
| 681 cmp %edx, %eax | 694 cmp %edx, %eax |
| 682 jne fatal_error | 695 jne fatal_error |
| 683 pop %eax | 696 pop %eax |
| 684 | 697 |
| 685 // Returning to the place where clone() had been called. We rely on | 698 // Returning to the place where clone() had been called. We rely on |
| 686 // using sigreturn() for restoring our registers. The caller already | 699 // using sigreturn() for restoring our registers. The caller already |
| 687 // created a signal stack frame and patched the register values | 700 // created a signal stack frame and patched the register values |
| 688 // with the ones that were in effect prior to calling sandbox_clone(). | 701 // with the ones that were in effect prior to calling sandbox_clone(). |
| 689 mov $__NR_sigreturn, %eax | 702 mov $__NR_sigreturn, %eax |
| 690 int $0x80 | 703 int $0x80 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 702 | 715 |
| 703 .bss | 716 .bss |
| 704 // Reserve space for sendmsg() data. This is used in a fork()'d | 717 // Reserve space for sendmsg() data. This is used in a fork()'d |
| 705 // helper process, so in principle this could safely overlap and | 718 // helper process, so in principle this could safely overlap and |
| 706 // overwrite other data, but it is such a small amount of memory | 719 // overwrite other data, but it is such a small amount of memory |
| 707 // that it is not worth trying to do that. The only requirement | 720 // that it is not worth trying to do that. The only requirement |
| 708 // is that this must be in a MAP_PRIVATE mapping so that an | 721 // is that this must be in a MAP_PRIVATE mapping so that an |
| 709 // untrusted thread cannot modify the forked subprocess's copy. | 722 // untrusted thread cannot modify the forked subprocess's copy. |
| 710 sendmsg_data: | 723 sendmsg_data: |
| 711 .space 0x50 | 724 .space 0x50 |
| OLD | NEW |