diff options
Diffstat (limited to 'kernel/panic.c')
-rw-r--r-- | kernel/panic.c | 47 |
1 files changed, 0 insertions, 47 deletions
diff --git a/kernel/panic.c b/kernel/panic.c index 87445a894c3a..c35c9eca3eb2 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -329,62 +329,15 @@ EXPORT_SYMBOL(warn_on_slowpath); | |||
329 | #warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this. | 329 | #warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this. |
330 | #endif | 330 | #endif |
331 | 331 | ||
332 | static unsigned long __stack_check_testing; | ||
333 | |||
334 | /* | ||
335 | * Self test function for the stack-protector feature. | ||
336 | * This test requires that the local variable absolutely has | ||
337 | * a stack slot. | ||
338 | */ | ||
339 | static noinline void __stack_chk_test_func(void) | ||
340 | { | ||
341 | unsigned long dummy_buffer[64]; /* force gcc to use the canary */ | ||
342 | |||
343 | current->stack_canary = ~current->stack_canary; | ||
344 | refresh_stack_canary(); | ||
345 | dummy_buffer[3] = 1; /* fool gcc into keeping the variable */ | ||
346 | } | ||
347 | |||
348 | static int __stack_chk_test(void) | ||
349 | { | ||
350 | printk(KERN_INFO "Testing -fstack-protector-all feature\n"); | ||
351 | __stack_check_testing = (unsigned long)&__stack_chk_test_func; | ||
352 | __stack_chk_test_func(); | ||
353 | if (__stack_check_testing) { | ||
354 | printk(KERN_ERR "-fstack-protector-all test failed\n"); | ||
355 | WARN_ON(1); | ||
356 | }; | ||
357 | current->stack_canary = ~current->stack_canary; | ||
358 | refresh_stack_canary(); | ||
359 | return 0; | ||
360 | } | ||
361 | /* | 332 | /* |
362 | * Called when gcc's -fstack-protector feature is used, and | 333 | * Called when gcc's -fstack-protector feature is used, and |
363 | * gcc detects corruption of the on-stack canary value | 334 | * gcc detects corruption of the on-stack canary value |
364 | */ | 335 | */ |
365 | void __stack_chk_fail(void) | 336 | void __stack_chk_fail(void) |
366 | { | 337 | { |
367 | if (__stack_check_testing == (unsigned long)&__stack_chk_test_func) { | ||
368 | long delta; | ||
369 | |||
370 | delta = (unsigned long)__builtin_return_address(0) - | ||
371 | __stack_check_testing; | ||
372 | /* | ||
373 | * The test needs to happen inside the test function, so | ||
374 | * check if the return address is close to that function. | ||
375 | * The function is only 2 dozen bytes long, but keep a wide | ||
376 | * safety margin to avoid panic()s for normal users regardless | ||
377 | * of the quality of the compiler. | ||
378 | */ | ||
379 | if (delta >= 0 && delta <= 400) { | ||
380 | __stack_check_testing = 0; | ||
381 | return; | ||
382 | } | ||
383 | } | ||
384 | panic("stack-protector: Kernel stack is corrupted in: %p\n", | 338 | panic("stack-protector: Kernel stack is corrupted in: %p\n", |
385 | __builtin_return_address(0)); | 339 | __builtin_return_address(0)); |
386 | } | 340 | } |
387 | EXPORT_SYMBOL(__stack_chk_fail); | 341 | EXPORT_SYMBOL(__stack_chk_fail); |
388 | 342 | ||
389 | late_initcall(__stack_chk_test); | ||
390 | #endif | 343 | #endif |