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

Side by Side Diff: fault_handler_i386.S

Issue 8036047: In 32bit mode, removed all assembly addressing modes that are incompatible with (Closed) Base URL: http://seccompsandbox.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 2 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 | « no previous file | sigaction.cc » ('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 <asm/unistd.h> 5 #include <asm/unistd.h>
6 6
7 7
8 .internal playground$segvSignalHandler 8 .internal playground$segvSignalHandler
9 .global playground$segvSignalHandler 9 .global playground$segvSignalHandler
10 playground$segvSignalHandler: 10 playground$segvSignalHandler:
11 // Inspect instruction at the point where the segmentation fault 11 // Inspect instruction at the point where the segmentation fault
12 // happened. If it is RDTSC, forward the request to the trusted 12 // happened. If it is RDTSC, forward the request to the trusted
13 // thread. 13 // thread.
14 mov $-3, %ebx // request for RDTSC 14 mov $-3, %ebx // request for RDTSC
15 mov 0xDC(%esp), %ebp // %eip at time of segmentation fault 15 mov 0xDC(%esp), %ebp // %eip at time of segmentation fault
16 cmpw $0x310F, (%ebp) // RDTSC 16 cmpw $0x310F, (%ebp) // RDTSC
17 jz 0f 17 jz 1f
18 cmpw $0x010F, (%ebp) // RDTSCP 18 cmpw $0x010F, (%ebp) // RDTSCP
19 jnz 10f 19 jnz 12f
20 cmpb $0xF9, 2(%ebp) 20 cmpb $0xF9, 2(%ebp)
21 jnz 10f 21 jnz 12f
22 mov $-4, %ebx // request for RDTSCP 22 mov $-4, %ebx // request for RDTSCP
23 0: 23 1:
24 #ifndef NDEBUG 24 #ifndef NDEBUG
25 lea 100f, %eax 25 call 2f
26 push %eax 26 2:addl $(100f-.), 0(%esp)
27 call playground$debugMessage 27 call playground$debugMessage@PLT
28 sub $4, %esp 28 sub $4, %esp
29 #else 29 #else
30 sub $8, %esp // allocate buffer for receiving timestamp 30 sub $8, %esp // allocate buffer for receiving timestamp
31 #endif 31 #endif
32 push %ebx 32 push %ebx
33 mov %fs:16, %ebx // fd = threadFdPub 33 mov %fs:16, %ebx // fd = threadFdPub
34 mov %esp, %ecx // buf = %esp 34 mov %esp, %ecx // buf = %esp
35 mov $4, %edx // len = sizeof(int) 35 mov $4, %edx // len = sizeof(int)
36 1:mov %edx, %eax // NR_write 36 3:mov %edx, %eax // NR_write
37 int $0x80 37 int $0x80
38 cmp %eax, %edx 38 cmp %eax, %edx
39 jz 8f 39 jz 10f
40 cmp $-4, %eax // EINTR 40 cmp $-4, %eax // EINTR
41 jz 1b 41 jz 3b
42 2:add $12, %esp // remove temporary buffer from stack 42 4:add $12, %esp // remove temporary buffer from stack
43 xor %eax, %eax 43 xor %eax, %eax
44 movl $0, 0xC8(%esp) // %edx at time of segmentation fault 44 movl $0, 0xC8(%esp) // %edx at time of segmentation fault
45 cmpw $0x310F, (%ebp) // RDTSC 45 cmpw $0x310F, (%ebp) // RDTSC
46 jz 3f 46 jz 5f
47 movl $0, 0xCC(%esp) // %ecx at time of segmentation fault 47 movl $0, 0xCC(%esp) // %ecx at time of segmentation fault
48 3:mov %eax, 0xD0(%esp) // %eax at time of segmentation fault 48 5:mov %eax, 0xD0(%esp) // %eax at time of segmentation fault
49 4:mov 0xDC(%esp), %ebp // %eip at time of segmentation fault 49 6:mov 0xDC(%esp), %ebp // %eip at time of segmentation fault
50 addl $2, 0xDC(%esp) // %eip at time of segmentation fault 50 addl $2, 0xDC(%esp) // %eip at time of segmentation fault
51 cmpw $0x010F, (%ebp) // RDTSCP 51 cmpw $0x010F, (%ebp) // RDTSCP
52 jnz 5f 52 jnz 7f
53 addl $1, 0xDC(%esp) // %eip at time of segmentation fault 53 addl $1, 0xDC(%esp) // %eip at time of segmentation fault
54 5:add $0x4, %esp 54 7:add $0x4, %esp
55 6:sub $0x1CC, %esp // a legacy signal stack is much larger 55 8:sub $0x1CC, %esp // a legacy signal stack is much larger
56 mov 0x1CC(%esp), %eax // push signal number 56 mov 0x1CC(%esp), %eax // push signal number
57 push %eax 57 push %eax
58 lea 0x270(%esp), %esi // copy siginfo register values 58 lea 0x270(%esp), %esi // copy siginfo register values
59 lea 0x4(%esp), %edi // into new location 59 lea 0x4(%esp), %edi // into new location
60 mov $22, %ecx 60 mov $22, %ecx
61 cld 61 cld
62 rep movsl 62 rep movsl
63 mov 0x2C8(%esp), %ebx // copy first half of signal mask 63 mov 0x2C8(%esp), %ebx // copy first half of signal mask
64 mov %ebx, 0x54(%esp) 64 mov %ebx, 0x54(%esp)
65 7:pop %eax // remove dummy argument (signo) 65 9:pop %eax // remove dummy argument (signo)
66 mov $119, %eax // NR_sigreturn 66 mov $119, %eax // NR_sigreturn
67 int $0x80 67 int $0x80
68 8:mov $12, %edx // len = 3*sizeof(int) 68 10:mov $12, %edx // len = 3*sizeof(int)
69 9:mov $3, %eax // NR_read 69 11:mov $3, %eax // NR_read
70 int $0x80 70 int $0x80
71 cmp $-4, %eax // EINTR 71 cmp $-4, %eax // EINTR
72 jz 9b 72 jz 11b
73 cmp %eax, %edx 73 cmp %eax, %edx
74 jnz 2b 74 jnz 4b
75 pop %eax 75 pop %eax
76 pop %edx 76 pop %edx
77 pop %ecx 77 pop %ecx
78 mov %edx, 0xC8(%esp) // %edx at time of segmentation fault 78 mov %edx, 0xC8(%esp) // %edx at time of segmentation fault
79 cmpw $0x310F, (%ebp) // RDTSC 79 cmpw $0x310F, (%ebp) // RDTSC
80 jz 3b 80 jz 5b
81 mov %ecx, 0xCC(%esp) // %ecx at time of segmentation fault 81 mov %ecx, 0xCC(%esp) // %ecx at time of segmentation fault
82 jmp 3b 82 jmp 5b
83 83
84 // If the instruction is INT 0, then this was probably the result 84 // If the instruction is INT 0, then this was probably the result
85 // of playground::Library being unable to find a way to safely 85 // of playground::Library being unable to find a way to safely
86 // rewrite the system call instruction. Retrieve the CPU register 86 // rewrite the system call instruction. Retrieve the CPU register
87 // at the time of the segmentation fault and invoke 87 // at the time of the segmentation fault and invoke
88 // syscallEntryPointWithFrame(). 88 // syscallEntryPointWithFrame().
89 10:cmpw $0x00CD, (%ebp) // INT $0x0 89 12:cmpw $0x00CD, (%ebp) // INT $0x0
90 jnz 20f 90 jnz 23f
91 cmpl $__NR_clone + 0xF001, 0xD0(%esp) 91 cmpl $__NR_clone + 0xF001, 0xD0(%esp)
92 jz .L_handle_callback_request 92 jz .L_handle_callback_request
93 #ifndef NDEBUG 93 #ifndef NDEBUG
94 lea 200f, %eax 94 call 1010f
95 push %eax 95 1010:addl $(200f-.), 0(%esp)
96 call playground$debugMessage 96 call playground$debugMessage@PLT
97 add $0x4, %esp 97 add $0x4, %esp
98 #endif 98 #endif
99 mov 0xD0(%esp), %eax // %eax at time of segmentation fault 99 mov 0xD0(%esp), %eax // %eax at time of segmentation fault
100 mov 0xC4(%esp), %ebx // %ebx at time of segmentation fault 100 mov 0xC4(%esp), %ebx // %ebx at time of segmentation fault
101 mov 0xCC(%esp), %ecx // %ecx at time of segmentation fault 101 mov 0xCC(%esp), %ecx // %ecx at time of segmentation fault
102 mov 0xC8(%esp), %edx // %edx at time of segmentation fault 102 mov 0xC8(%esp), %edx // %edx at time of segmentation fault
103 mov 0xB8(%esp), %esi // %esi at time of segmentation fault 103 mov 0xB8(%esp), %esi // %esi at time of segmentation fault
104 mov 0xB4(%esp), %edi // %edi at time of segmentation fault 104 mov 0xB4(%esp), %edi // %edi at time of segmentation fault
105 mov 0xBC(%esp), %ebp // %ebp at time of segmentation fault 105 mov 0xBC(%esp), %ebp // %ebp at time of segmentation fault
106 106
107 // Handle sigprocmask() and rt_sigprocmask() 107 // Handle sigprocmask() and rt_sigprocmask()
108 cmp $175, %eax // NR_rt_sigprocmask 108 cmp $175, %eax // NR_rt_sigprocmask
109 jnz 11f 109 jnz 13f
110 mov $-22, %eax // -EINVAL 110 mov $-22, %eax // -EINVAL
111 cmp $8, %esi // %esi = sigsetsize (8 bytes = 64 signals) 111 cmp $8, %esi // %esi = sigsetsize (8 bytes = 64 signals)
112 jl 3b 112 jl 5b
113 jmp 12f 113 jmp 14f
114 11:cmp $126, %eax // NR_sigprocmask 114 13:cmp $126, %eax // NR_sigprocmask
115 jnz 16f 115 jnz 18f
116 mov $-22, %eax 116 mov $-22, %eax
117 12:mov 0xFC(%esp), %edi // signal mask at time of segmentation fault 117 14:mov 0xFC(%esp), %edi // signal mask at time of segmentation fault
118 mov 0x100(%esp), %ebp 118 mov 0x100(%esp), %ebp
119 test %ecx, %ecx // only set mask, if set is non-NULL 119 test %ecx, %ecx // only set mask, if set is non-NULL
120 jz 15f 120 jz 17f
121 mov 0(%ecx), %esi 121 mov 0(%ecx), %esi
122 mov 4(%ecx), %ecx 122 mov 4(%ecx), %ecx
123 cmp $0, %ebx // %ebx = how (SIG_BLOCK) 123 cmp $0, %ebx // %ebx = how (SIG_BLOCK)
124 jnz 13f 124 jnz 15f
125 or %esi, 0xFC(%esp) // signal mask at time of segmentation fault 125 or %esi, 0xFC(%esp) // signal mask at time of segmentation fault
126 or %ecx, 0x100(%esp) 126 or %ecx, 0x100(%esp)
127 jmp 15f 127 jmp 17f
128 13:cmp $1, %ebx // %ebx = how (SIG_UNBLOCK) 128 15:cmp $1, %ebx // %ebx = how (SIG_UNBLOCK)
129 jnz 14f 129 jnz 16f
130 xor $-1, %esi 130 xor $-1, %esi
131 xor $-1, %ecx 131 xor $-1, %ecx
132 and %esi, 0xFC(%esp) // signal mask at time of segmentation fault 132 and %esi, 0xFC(%esp) // signal mask at time of segmentation fault
133 and %ecx, 0x100(%esp) 133 and %ecx, 0x100(%esp)
134 jmp 15f 134 jmp 17f
135 14:cmp $2, %ebx // %ebx = how (SIG_SETMASK) 135 16:cmp $2, %ebx // %ebx = how (SIG_SETMASK)
136 jnz 3b 136 jnz 5b
137 mov %esi, 0xFC(%esp) // signal mask at time of segmentation fault 137 mov %esi, 0xFC(%esp) // signal mask at time of segmentation fault
138 mov %ecx, 0x100(%esp) 138 mov %ecx, 0x100(%esp)
139 15:xor %eax, %eax 139 17:xor %eax, %eax
140 test %edx, %edx // only return old mask, if set is non-NULL 140 test %edx, %edx // only return old mask, if set is non-NULL
141 jz 3b 141 jz 5b
142 mov %edi, 0(%edx) // old_set 142 mov %edi, 0(%edx) // old_set
143 mov %ebp, 4(%edx) 143 mov %ebp, 4(%edx)
144 jmp 3b 144 jmp 5b
145 145
146 // Handle sigreturn() and rt_sigreturn() 146 // Handle sigreturn() and rt_sigreturn()
147 // See syscall.cc for a discussion on how we can emulate rt_sigreturn() 147 // See syscall.cc for a discussion on how we can emulate rt_sigreturn()
148 // by calling sigreturn() with a suitably adjusted stack. 148 // by calling sigreturn() with a suitably adjusted stack.
149 16:cmp $119, %eax // NR_sigreturn 149 18:cmp $119, %eax // NR_sigreturn
150 jnz 17f 150 jnz 19f
151 mov 0xC0(%esp), %esp // %esp at time of segmentation fault 151 mov 0xC0(%esp), %esp // %esp at time of segmentation fault
152 int $0x80 // sigreturn() is unrestricted 152 int $0x80 // sigreturn() is unrestricted
153 17:cmp $173, %eax // NR_rt_sigreturn 153 19:cmp $173, %eax // NR_rt_sigreturn
154 jnz 18f 154 jnz 20f
155 mov 0xC0(%esp), %esp // %esp at time of segmentation fault 155 mov 0xC0(%esp), %esp // %esp at time of segmentation fault
156 sub $4, %esp // add fake return address 156 sub $4, %esp // add fake return address
157 jmp 4b 157 jmp 6b
158 158
159 // Copy signal frame onto new stack. In the process, we have to convert 159 // Copy signal frame onto new stack. In the process, we have to convert
160 // it from an RT signal frame to a legacy signal frame. 160 // it from an RT signal frame to a legacy signal frame.
161 // See clone.cc for details 161 // See clone.cc for details
162 18:cmp $120+0xF000, %eax // NR_clone + 0xF000 162 20:cmp $120+0xF000, %eax // NR_clone + 0xF000
163 jnz 19f 163 jnz 21f
164 lea -0x1C8(%esp), %eax // retain stack frame upon returning 164 lea -0x1C8(%esp), %eax // retain stack frame upon returning
165 mov %eax, 0xC0(%esp) // %esp at time of segmentation fault 165 mov %eax, 0xC0(%esp) // %esp at time of segmentation fault
166 jmp 3b 166 jmp 5b
167 167
168 // Forward system call to syscallEntryPointWithFrame() 168 // Forward system call to syscallEntryPointWithFrame()
169 19:push $3b 169 21:call 22f
170 22:subl $(.-5b), 0(%esp)
170 push 0xE0(%esp) // %eip at time of segmentation fault 171 push 0xE0(%esp) // %eip at time of segmentation fault
171 jmp playground$syscallEntryPointWithFrame 172 jmp playground$syscallEntryPointWithFrame@PLT
172 173
173 // This was a genuine segmentation fault. Check Sandbox::sa_segv_ for 174 // This was a genuine segmentation fault. Check Sandbox::sa_segv_ for
174 // what we are supposed to do. 175 // what we are supposed to do.
175 // In order to implement SA_NODEFER, we have to keep track of recursive 176 // In order to implement SA_NODEFER, we have to keep track of recursive
176 // calls to SIGSEGV handlers. This means we have to increment a counter 177 // calls to SIGSEGV handlers. This means we have to increment a counter
177 // before calling the user's signal handler, and decrement it on 178 // before calling the user's signal handler, and decrement it on
178 // leaving the user's signal handler. 179 // leaving the user's signal handler.
179 // N.B. We currently do not correctly adjust the SEGV counter, if the 180 // N.B. We currently do not correctly adjust the SEGV counter, if the
180 // user's signal handler exits in way other than by returning (e.g. by 181 // user's signal handler exits in way other than by returning (e.g. by
181 // directly calling {,rt_}sigreturn(), or by calling siglongjmp()). 182 // directly calling {,rt_}sigreturn(), or by calling siglongjmp()).
182 // N.B. On i386, we don't have any guarantees that NX protection works. 183 // N.B. On i386, we don't have any guarantees that NX protection works.
183 // So, we don't even attempt to fake a correct restorer function. Some 184 // So, we don't even attempt to fake a correct restorer function. Some
184 // callers might be confused by this and will need fixing for running 185 // callers might be confused by this and will need fixing for running
185 // inside of the seccomp sandbox. 186 // inside of the seccomp sandbox.
186 20:lea playground$sa_segv, %eax 187 23:call 24f
188 24:pop %eax
189 add $(_GLOBAL_OFFSET_TABLE_+(.-24b)), %eax
190 lea playground$sa_segv@GOTOFF(%eax), %eax
187 cmpl $0, 0(%eax) // SIG_DFL 191 cmpl $0, 0(%eax) // SIG_DFL
188 jz 21f 192 jz 25f
189 cmpl $1, 0(%eax) // SIG_IGN 193 cmpl $1, 0(%eax) // SIG_IGN
190 jnz 22f // can't really ignore synchronous signals 194 jnz 26f // can't really ignore synchronous signals
191 195
192 // Trigger the kernel's default signal disposition. The only way we can 196 // Trigger the kernel's default signal disposition. The only way we can
193 // do this from seccomp mode is by blocking the signal and retriggering 197 // do this from seccomp mode is by blocking the signal and retriggering
194 // it. 198 // it.
195 21:orb $4, 0xFD(%esp) // signal mask at time of segmentation fault 199 25:orb $4, 0xFD(%esp) // signal mask at time of segmentation fault
196 jmp 5b 200 jmp 7b
197 201
198 // Check sa_flags: 202 // Check sa_flags:
199 // - We can ignore SA_NOCLDSTOP, SA_NOCLDWAIT, and SA_RESTART as they 203 // - We can ignore SA_NOCLDSTOP, SA_NOCLDWAIT, and SA_RESTART as they
200 // do not have any effect for SIGSEGV. 204 // do not have any effect for SIGSEGV.
201 // - We have to always register our signal handler with SA_NODEFER so 205 // - We have to always register our signal handler with SA_NODEFER so
202 // that the user's signal handler can make system calls which might 206 // that the user's signal handler can make system calls which might
203 // require additional help from our SEGV handler. 207 // require additional help from our SEGV handler.
204 // - If the user's signal handler wasn't supposed to be SA_NODEFER, 208 // - If the user's signal handler wasn't supposed to be SA_NODEFER,
205 // then we emulate this behavior by keeping track of a recursion 209 // then we emulate this behavior by keeping track of a recursion
206 // counter. 210 // counter.
207 // 211 //
208 // TODO(markus): If/when we add support for sigaltstack(), we have to 212 // TODO(markus): If/when we add support for sigaltstack(), we have to
209 // handle SA_ONSTACK. 213 // handle SA_ONSTACK.
210 22:cmpl $0, %fs:0x1040-0x58 // check if we failed inside of SEGV handler 214 26:cmpl $0, %fs:0x1040-0x58 // check if we failed inside of SEGV handler
211 jnz 21b // if so, then terminate program 215 jnz 25b // if so, then terminate program
212 mov 0(%eax), %ebx // sa_segv_.sa_sigaction 216 mov 0(%eax), %ebx // sa_segv_.sa_sigaction
213 mov 4(%eax), %ecx // sa_segv_.sa_flags 217 mov 4(%eax), %ecx // sa_segv_.sa_flags
214 btl $31, %ecx // SA_RESETHAND 218 btl $31, %ecx // SA_RESETHAND
215 jnc 23f 219 jnc 27f
216 movl $0, 0(%eax) // set handler to SIG_DFL 220 movl $0, 0(%eax) // set handler to SIG_DFL
217 23:btl $30, %ecx // SA_NODEFER 221 27:btl $30, %ecx // SA_NODEFER
218 jc 26f 222 jc 32f
219 btl $2, %ecx // SA_SIGINFO 223 btl $2, %ecx // SA_SIGINFO
220 jnc 24f 224 jnc 29f
221 movl $27f, 0(%esp) // set appropriate restorer function 225 add $4, %esp
226 call 28f
227 28:addl $(35f-.), 0(%esp) // set appropriate restorer function
222 incl %fs:0x1040-0x58 // increment recursion counter 228 incl %fs:0x1040-0x58 // increment recursion counter
223 jmp *%ebx // call user's signal handler 229 jmp *%ebx // call user's signal handler
224 24:movl $28f, 0(%esp) 230 29:add $4, %esp
231 call 30f
232 30:addl $(36f-.), 0(%esp)
225 incl %fs:0x1040-0x58 // increment recursion counter 233 incl %fs:0x1040-0x58 // increment recursion counter
226 234
227 // We always register the signal handler to give us rt-style signal 235 // We always register the signal handler to give us rt-style signal
228 // frames. But if the user asked for legacy signal frames, we must 236 // frames. But if the user asked for legacy signal frames, we must
229 // convert the signal frame prior to calling the user's signal handler. 237 // convert the signal frame prior to calling the user's signal handler.
230 25:sub $0x1C8, %esp // a legacy signal stack is much larger 238 31:sub $0x1C8, %esp // a legacy signal stack is much larger
231 mov 0x1CC(%esp), %eax // push signal number 239 mov 0x1CC(%esp), %eax // push signal number
232 push %eax 240 push %eax
233 mov 0x1CC(%esp), %eax // push restorer function 241 mov 0x1CC(%esp), %eax // push restorer function
234 push %eax 242 push %eax
235 lea 0x274(%esp), %esi // copy siginfo register values 243 lea 0x274(%esp), %esi // copy siginfo register values
236 lea 0x8(%esp), %edi // into new location 244 lea 0x8(%esp), %edi // into new location
237 mov $22, %ecx 245 mov $22, %ecx
238 cld 246 cld
239 rep movsl 247 rep movsl
240 mov 0x2CC(%esp), %eax // copy first half of signal mask 248 mov 0x2CC(%esp), %eax // copy first half of signal mask
241 mov %eax, 0x58(%esp) 249 mov %eax, 0x58(%esp)
242 jmp *%ebx // call user's signal handler 250 jmp *%ebx // call user's signal handler
243 26:movl $7b, 0(%esp) // set appropriate restorer function 251 32:add $4, %esp
252 call 33f
253 33:addl $(9b-.), 0(%esp) // set appropriate restorer function
244 btl $2, %ecx // SA_SIGINFO 254 btl $2, %ecx // SA_SIGINFO
245 jnc 25b 255 jnc 31b
246 movl $6b, 0(%esp) // set appropriate restorer function 256 add $4, %esp
257 call 34f
258 34:addl $(8b-.), 0(%esp) // set appropriate restorer function
247 jmp *%ebx // call user's signal handler 259 jmp *%ebx // call user's signal handler
248 27:decl %fs:0x1040-0x58 260 35:decl %fs:0x1040-0x58
249 jmp 6b 261 jmp 8b
250 28:decl %fs:0x1040-0x58 262 36:decl %fs:0x1040-0x58
251 jmp 7b 263 jmp 9b
252 264
253 .L_handle_callback_request: 265 .L_handle_callback_request:
254 mov 0xC8(%esp), %eax // %edx at time of segmentation fault 266 mov 0xC8(%esp), %eax // %edx at time of segmentation fault
255 jmp *%eax 267 jmp *%eax
OLDNEW
« no previous file with comments | « no previous file | sigaction.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698