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 |