@@ -135,41 +135,72 @@ static struct pt_regs *decode_frame_pointer(unsigned long *bp)
135
135
return (struct pt_regs * )(regs & ~0x1 );
136
136
}
137
137
138
- static bool update_stack_state (struct unwind_state * state , void * addr ,
139
- size_t len )
138
+ static bool update_stack_state (struct unwind_state * state ,
139
+ unsigned long * next_bp )
140
140
{
141
141
struct stack_info * info = & state -> stack_info ;
142
- enum stack_type orig_type = info -> type ;
142
+ enum stack_type prev_type = info -> type ;
143
+ struct pt_regs * regs ;
144
+ unsigned long * frame , * prev_frame_end ;
145
+ size_t len ;
146
+
147
+ if (state -> regs )
148
+ prev_frame_end = (void * )state -> regs + regs_size (state -> regs );
149
+ else
150
+ prev_frame_end = (void * )state -> bp + FRAME_HEADER_SIZE ;
151
+
152
+ /* Is the next frame pointer an encoded pointer to pt_regs? */
153
+ regs = decode_frame_pointer (next_bp );
154
+ if (regs ) {
155
+ frame = (unsigned long * )regs ;
156
+ len = regs_size (regs );
157
+ } else {
158
+ frame = next_bp ;
159
+ len = FRAME_HEADER_SIZE ;
160
+ }
143
161
144
162
/*
145
- * If addr isn't on the current stack, switch to the next one.
163
+ * If the next bp isn't on the current stack, switch to the next one.
146
164
*
147
165
* We may have to traverse multiple stacks to deal with the possibility
148
- * that ' info->next_sp' could point to an empty stack and 'addr' could
149
- * be on a subsequent stack.
166
+ * that info->next_sp could point to an empty stack and the next bp
167
+ * could be on a subsequent stack.
150
168
*/
151
- while (!on_stack (info , addr , len ))
169
+ while (!on_stack (info , frame , len ))
152
170
if (get_stack_info (info -> next_sp , state -> task , info ,
153
171
& state -> stack_mask ))
154
172
return false;
155
173
156
- if (!state -> orig_sp || info -> type != orig_type )
157
- state -> orig_sp = addr ;
174
+ /* Make sure it only unwinds up and doesn't overlap the prev frame: */
175
+ if (state -> orig_sp && state -> stack_info .type == prev_type &&
176
+ frame < prev_frame_end )
177
+ return false;
178
+
179
+ /* Move state to the next frame: */
180
+ if (regs ) {
181
+ state -> regs = regs ;
182
+ state -> bp = NULL ;
183
+ } else {
184
+ state -> bp = next_bp ;
185
+ state -> regs = NULL ;
186
+ }
187
+
188
+ /* Save the original stack pointer for unwind_dump(): */
189
+ if (!state -> orig_sp || info -> type != prev_type )
190
+ state -> orig_sp = frame ;
158
191
159
192
return true;
160
193
}
161
194
162
195
bool unwind_next_frame (struct unwind_state * state )
163
196
{
164
197
struct pt_regs * regs ;
165
- unsigned long * next_bp , * next_frame ;
166
- size_t next_len ;
167
- enum stack_type prev_type = state -> stack_info .type ;
198
+ unsigned long * next_bp ;
168
199
169
200
if (unwind_done (state ))
170
201
return false;
171
202
172
- /* have we reached the end? */
203
+ /* Have we reached the end? */
173
204
if (state -> regs && user_mode (state -> regs ))
174
205
goto the_end ;
175
206
@@ -200,24 +231,14 @@ bool unwind_next_frame(struct unwind_state *state)
200
231
return true;
201
232
}
202
233
203
- /* get the next frame pointer */
234
+ /* Get the next frame pointer: */
204
235
if (state -> regs )
205
236
next_bp = (unsigned long * )state -> regs -> bp ;
206
237
else
207
- next_bp = (unsigned long * )READ_ONCE_TASK_STACK (state -> task ,* state -> bp );
238
+ next_bp = (unsigned long * )READ_ONCE_TASK_STACK (state -> task , * state -> bp );
208
239
209
- /* is the next frame pointer an encoded pointer to pt_regs? */
210
- regs = decode_frame_pointer (next_bp );
211
- if (regs ) {
212
- next_frame = (unsigned long * )regs ;
213
- next_len = sizeof (* regs );
214
- } else {
215
- next_frame = next_bp ;
216
- next_len = FRAME_HEADER_SIZE ;
217
- }
218
-
219
- /* make sure the next frame's data is accessible */
220
- if (!update_stack_state (state , next_frame , next_len )) {
240
+ /* Move to the next frame if it's safe: */
241
+ if (!update_stack_state (state , next_bp )) {
221
242
/*
222
243
* Don't warn on bad regs->bp. An interrupt in entry code
223
244
* might cause a false positive warning.
@@ -228,24 +249,6 @@ bool unwind_next_frame(struct unwind_state *state)
228
249
goto bad_address ;
229
250
}
230
251
231
- /* Make sure it only unwinds up and doesn't overlap the last frame: */
232
- if (state -> stack_info .type == prev_type ) {
233
- if (state -> regs && (void * )next_frame < (void * )state -> regs + regs_size (state -> regs ))
234
- goto bad_address ;
235
-
236
- if (state -> bp && (void * )next_frame < (void * )state -> bp + FRAME_HEADER_SIZE )
237
- goto bad_address ;
238
- }
239
-
240
- /* move to the next frame */
241
- if (regs ) {
242
- state -> regs = regs ;
243
- state -> bp = NULL ;
244
- } else {
245
- state -> bp = next_bp ;
246
- state -> regs = NULL ;
247
- }
248
-
249
252
return true;
250
253
251
254
bad_address :
@@ -263,13 +266,13 @@ bool unwind_next_frame(struct unwind_state *state)
263
266
printk_deferred_once (KERN_WARNING
264
267
"WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n" ,
265
268
state -> regs , state -> task -> comm ,
266
- state -> task -> pid , next_frame );
269
+ state -> task -> pid , next_bp );
267
270
unwind_dump (state , (unsigned long * )state -> regs );
268
271
} else {
269
272
printk_deferred_once (KERN_WARNING
270
273
"WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n" ,
271
274
state -> bp , state -> task -> comm ,
272
- state -> task -> pid , next_frame );
275
+ state -> task -> pid , next_bp );
273
276
unwind_dump (state , state -> bp );
274
277
}
275
278
the_end :
@@ -281,35 +284,23 @@ EXPORT_SYMBOL_GPL(unwind_next_frame);
281
284
void __unwind_start (struct unwind_state * state , struct task_struct * task ,
282
285
struct pt_regs * regs , unsigned long * first_frame )
283
286
{
284
- unsigned long * bp , * frame ;
285
- size_t len ;
287
+ unsigned long * bp ;
286
288
287
289
memset (state , 0 , sizeof (* state ));
288
290
state -> task = task ;
289
291
290
- /* don 't even attempt to start from user mode regs */
292
+ /* Don 't even attempt to start from user mode regs: */
291
293
if (regs && user_mode (regs )) {
292
294
state -> stack_info .type = STACK_TYPE_UNKNOWN ;
293
295
return ;
294
296
}
295
297
296
- /* set up the starting stack frame */
297
298
bp = get_frame_pointer (task , regs );
298
- regs = decode_frame_pointer (bp );
299
- if (regs ) {
300
- state -> regs = regs ;
301
- frame = (unsigned long * )regs ;
302
- len = sizeof (* regs );
303
- } else {
304
- state -> bp = bp ;
305
- frame = bp ;
306
- len = FRAME_HEADER_SIZE ;
307
- }
308
299
309
- /* initialize stack info and make sure the frame data is accessible */
310
- get_stack_info (frame , state -> task , & state -> stack_info ,
300
+ /* Initialize stack info and make sure the frame data is accessible: */
301
+ get_stack_info (bp , state -> task , & state -> stack_info ,
311
302
& state -> stack_mask );
312
- update_stack_state (state , frame , len );
303
+ update_stack_state (state , bp );
313
304
314
305
/*
315
306
* The caller can provide the address of the first frame directly
0 commit comments