x86: fix kernel address printk exposures
Subsystems (9)
cover x86: fix kernel address printk exposures
These are some changes suggested by Linus to remove some kernel address exposures in printk. Most notably, the x86 stack dump no longer prints full kernel text addresses.
There's also a fix for the faddr2line script which is used for converting a function offset into a source code file name and line number.
Josh Poimboeuf (4):
scripts/faddr2line: fix "size mismatch" error x86/dumpstack: remove kernel text addresses from stack dump x86/dumpstack: remove raw stack dump
mm: remove kernel address exposure in free_reserved_area()
Documentation/kernel-parameters.txt | 3 -- Documentation/sysctl/kernel.txt | 8 ----- Documentation/x86/x86_64/boot-options.txt | 4 --- arch/x86/include/asm/kdebug.h | 1 - arch/x86/include/asm/stacktrace.h | 5 --- arch/x86/kernel/dumpstack.c | 39 ++++------------------- arch/x86/kernel/dumpstack_32.c | 33 +------------------ arch/x86/kernel/dumpstack_64.c | 53 +------------------------------ arch/x86/kernel/process_32.c | 7 ++-- arch/x86/kernel/process_64.c | 6 ++-- arch/x86/mm/fault.c | 3 +- arch/x86/platform/uv/uv_nmi.c | 4 +-- kernel/sysctl.c | 7 ---- mm/page_alloc.c | 4 +-- scripts/faddr2line | 33 ++++++++++++------- 15 files changed, 40 insertions(+), 170 deletions(-)
Signature · 1 line
2.7.4
PATCH 1/4 scripts/faddr2line: fix "size mismatch" error
I'm not sure how we missed this problem before. When I take a function address and size from an oops and give it to faddr2line, it usually complains about a size mismatch:
$ scripts/faddr2line ~/k/vmlinux write_sysrq_trigger+0x51/0x60 skipping write_sysrq_trigger address at 0xffffffff815731a1 due to size mismatch (0x60 != 83) no match for write_sysrq_trigger+0x51/0x60
The problem is caused by differences in how kallsyms and faddr2line determine a function's size.
kallsyms calculates a function's size by parsing the output of 'nm -n' and subtracting the next function's address from the current function's address. This means that nop instructions after the end of the function are included in the size.
In contrast, faddr2line reads the size from the symbol table, which does *not* include the ending nops in the function's size.
Change faddr2line to calculate the size from the output of 'nm -n' to be consistent with kallsyms and oops outputs.
--- scripts/faddr2line | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-)
scripts/faddr2line +21 -12
@@ -105,9 +105,18 @@ __faddr2line() { # In rare cases there might be duplicates. while read symbol; do local fields=($symbol) - local sym_base=0x${fields[1]} - local sym_size=${fields[2]} - local sym_type=${fields[3]} + local sym_base=0x${fields[0]} + local sym_type=${fields[1]} + local sym_end=0x${fields[3]} + + # calculate the size + local sym_size=$(($sym_end - $sym_base)) + if [[ -z $sym_size ]] || [[ $sym_size -le 0 ]]; then + warn "bad symbol size: base: $sym_base end: $sym_end" + DONE=1 + return + fi + sym_size=0x$(printf %x $sym_size) # calculate the address local addr=$(($sym_base + $offset))
@@ -116,26 +125,26 @@ __faddr2line() { DONE=1 return fi - local hexaddr=0x$(printf %x $addr) + addr=0x$(printf %x $addr) # weed out non-function symbols - if [[ $sym_type != "FUNC" ]]; then + if [[ $sym_type != t ]] && [[ $sym_type != T ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $hexaddr due to non-function symbol" + echo "skipping $func address at $addr due to non-function symbol of type '$sym_type'" continue fi # if the user provided a size, make sure it matches the symbol's size if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $hexaddr due to size mismatch ($size != $sym_size)" + echo "skipping $func address at $addr due to size mismatch ($size != $sym_size)" continue; fi # make sure the provided offset is within the symbol's range if [[ $offset -gt $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $hexaddr due to size mismatch ($offset > $sym_size)" + echo "skipping $func address at $addr due to size mismatch ($offset > $sym_size)" continue fi
@@ -143,12 +152,12 @@ __faddr2line() { [[ $FIRST = 0 ]] && echo FIRST=0 - local hexsize=0x$(printf %x $sym_size) - echo "$func+$offset/$hexsize:" - addr2line -fpie $objfile $hexaddr | sed "s; $dir_prefix\(\./\)*; ;" + # pass real address to addr2line + echo "$func+$offset/$sym_size:" + addr2line -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;" DONE=1 - done < <(readelf -sW $objfile | awk -v f=$func '$8 == f {print}') + done < <(nm -n $objfile | awk -v fn=$func '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, $1 }') } [[ $# -lt 2 ]] && usage
Signature · 1 line
2.7.4
tip-bot for Josh Poimboeuf
merge bot[tip:x86/asm] scripts/faddr2line: Fix "size mismatch" error
scripts/faddr2line: Fix "size mismatch" error
Commit-ID: efdb4167e676aaba7505bec739785b76e206cb45 Gitweb: http://git.kernel.org/tip/efdb4167e676aaba7505bec739785b76e206cb45 Author: Josh Poimboeuf <[email protected]> AuthorDate: Tue, 25 Oct 2016 09:51:11 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 25 Oct 2016 18:40:37 +0200
scripts/faddr2line: Fix "size mismatch" error
I'm not sure how we missed this problem before. When I take a function address and size from an oops and give it to faddr2line, it usually complains about a size mismatch:
$ scripts/faddr2line ~/k/vmlinux write_sysrq_trigger+0x51/0x60 skipping write_sysrq_trigger address at 0xffffffff815731a1 due to size mismatch (0x60 != 83) no match for write_sysrq_trigger+0x51/0x60
The problem is caused by differences in how kallsyms and faddr2line determine a function's size.
kallsyms calculates a function's size by parsing the output of 'nm -n' and subtracting the next function's address from the current function's address. This means that nop instructions after the end of the function are included in the size.
In contrast, faddr2line reads the size from the symbol table, which does *not* include the ending nops in the function's size.
Change faddr2line to calculate the size from the output of 'nm -n' to be consistent with kallsyms and oops outputs.
--- scripts/faddr2line | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-)
scripts/faddr2line +21 -12
@@ -105,9 +105,18 @@ __faddr2line() { # In rare cases there might be duplicates. while read symbol; do local fields=($symbol) - local sym_base=0x${fields[1]} - local sym_size=${fields[2]} - local sym_type=${fields[3]} + local sym_base=0x${fields[0]} + local sym_type=${fields[1]} + local sym_end=0x${fields[3]} + + # calculate the size + local sym_size=$(($sym_end - $sym_base)) + if [[ -z $sym_size ]] || [[ $sym_size -le 0 ]]; then + warn "bad symbol size: base: $sym_base end: $sym_end" + DONE=1 + return + fi + sym_size=0x$(printf %x $sym_size) # calculate the address local addr=$(($sym_base + $offset))
@@ -116,26 +125,26 @@ __faddr2line() { DONE=1 return fi - local hexaddr=0x$(printf %x $addr) + addr=0x$(printf %x $addr) # weed out non-function symbols - if [[ $sym_type != "FUNC" ]]; then + if [[ $sym_type != t ]] && [[ $sym_type != T ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $hexaddr due to non-function symbol" + echo "skipping $func address at $addr due to non-function symbol of type '$sym_type'" continue fi # if the user provided a size, make sure it matches the symbol's size if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $hexaddr due to size mismatch ($size != $sym_size)" + echo "skipping $func address at $addr due to size mismatch ($size != $sym_size)" continue; fi # make sure the provided offset is within the symbol's range if [[ $offset -gt $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $hexaddr due to size mismatch ($offset > $sym_size)" + echo "skipping $func address at $addr due to size mismatch ($offset > $sym_size)" continue fi
@@ -143,12 +152,12 @@ __faddr2line() { [[ $FIRST = 0 ]] && echo FIRST=0 - local hexsize=0x$(printf %x $sym_size) - echo "$func+$offset/$hexsize:" - addr2line -fpie $objfile $hexaddr | sed "s; $dir_prefix\(\./\)*; ;" + # pass real address to addr2line + echo "$func+$offset/$sym_size:" + addr2line -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;" DONE=1 - done < <(readelf -sW $objfile | awk -v f=$func '$8 == f {print}') + done < <(nm -n $objfile | awk -v fn=$func '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, $1 }') } [[ $# -lt 2 ]] && usage
PATCH 2/4 x86/dumpstack: remove kernel text addresses from stack dump
In reply to Josh PoimboeufPrinting kernel text addresses in stack dumps is of questionable value, especially now that address randomization is becoming common.
It can be a security issue because it leaks kernel addresses. It also affects the usefulness of the stack dump. Linus says:
"I actually spend time cleaning up commit messages in logs, because useless data that isn't actually information (random hex numbers) is actively detrimental.
It makes commit logs less legible.
It also makes it harder to parse dumps.
It's not useful. That makes it actively bad.
I probably look at more oops reports than most people. I have not found the hex numbers useful for the last five years, because they are just randomized crap.
The stack content thing just makes code scroll off the screen etc, for example."
The only real downside to removing these addresses is that they can be used to disambiguate duplicate symbol names. However such cases are rare, and the context of the stack dump should be enough to be able to figure it out.
There's now a 'faddr2line' script which can be used to convert a function address to a file name and line:
$ ./scripts/faddr2line ~/k/vmlinux write_sysrq_trigger+0x51/0x60 write_sysrq_trigger+0x51/0x60: write_sysrq_trigger at drivers/tty/sysrq.c:1098
Or gdb can be used:
$ echo "list *write_sysrq_trigger+0x51" |gdb ~/k/vmlinux |grep "is in" (gdb) 0xffffffff815b5d83 is in driver_probe_device (/home/jpoimboe/git/linux/drivers/base/dd.c:378).
(But note that when there are duplicate symbol names, gdb will only show the first symbol it finds. faddr2line is recommended over gdb because it handles duplicates and it also does function size checking.)
Here's an example of what a stack dump looks like after this change:
BUG: unable to handle kernel NULL pointer dereference at (null) IP: sysrq_handle_crash+0x45/0x80 PGD 36bfa067 [ 29.650644] PUD 7aca3067 50970] Oops: 0002 [#1] PREEMPT SMP Modules linked in: ... CPU: 1 PID: 786 Comm: bash Tainted: G E 4.9.0-rc1+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.1-1.fc24 04/01/2014 task: ffff880078582a40 task.stack: ffffc90000ba8000 RIP: 0010:sysrq_handle_crash+0x45/0x80 RSP: 0018:ffffc90000babdc8 EFLAGS: 00010296 RAX: ffff880078582a40 RBX: 0000000000000063 RCX: 0000000000000001 RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000292 RBP: ffffc90000babdc8 R08: 0000000b31866061 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000007 R14: ffffffff81ee8680 R15: 0000000000000000 FS: 00007ffb43869700(0000) GS:ffff88007d400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000007a3e9000 CR4: 00000000001406e0 Stack: ffffc90000babe00 ffffffff81572d08 ffffffff81572bd5 0000000000000002 0000000000000000 ffff880079606600 00007ffb4386e000 ffffc90000babe20 ffffffff81573201 ffff880036a3fd00 fffffffffffffffb ffffc90000babe40 Call Trace: __handle_sysrq+0x138/0x220 ? __handle_sysrq+0x5/0x220 write_sysrq_trigger+0x51/0x60 proc_reg_write+0x42/0x70 __vfs_write+0x37/0x140 ? preempt_count_sub+0xa1/0x100 ? __sb_start_write+0xf5/0x210 ? vfs_write+0x183/0x1a0 vfs_write+0xb8/0x1a0 SyS_write+0x58/0xc0 entry_SYSCALL_64_fastpath+0x1f/0xc2 RIP: 0033:0x7ffb42f55940 RSP: 002b:00007ffd33bb6b18 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000046 RCX: 00007ffb42f55940 RDX: 0000000000000002 RSI: 00007ffb4386e000 RDI: 0000000000000001 RBP: 0000000000000011 R08: 00007ffb4321ea40 R09: 00007ffb43869700 R10: 00007ffb43869700 R11: 0000000000000246 R12: 0000000000778a10 R13: 00007ffd33bb5c00 R14: 0000000000000007 R15: 0000000000000010 Code: 34 e8 d0 34 bc ff 48 c7 c2 3b 2b 57 81 be 01 00 00 00 48 c7 c7 e0 dd e5 81 e8 a8 55 ba ff c7 05 0e 3f de 00 01 00 00 00 0f ae f8 <c6> 04 25 00 00 00 00 01 5d c3 e8 4c 49 bc ff 84 c0 75 c3 48 c7 RIP: sysrq_handle_crash+0x45/0x80 RSP: ffffc90000babdc8 CR2: 0000000000000000
--- arch/x86/include/asm/kdebug.h | 1 - arch/x86/kernel/dumpstack.c | 18 ++++-------------- arch/x86/kernel/process_32.c | 7 +++---- arch/x86/kernel/process_64.c | 6 +++--- arch/x86/mm/fault.c | 3 +-- arch/x86/platform/uv/uv_nmi.c | 4 ++-- 6 files changed, 13 insertions(+), 26 deletions(-)
arch/x86/include/asm/kdebug.h +0 -1
@@ -21,7 +21,6 @@ enum die_val { DIE_NMIUNKNOWN, }; -extern void printk_address (unsigned long address);extern void die (const char *,struct pt_regs *,long );extern int __must_check __die (const char *,struct pt_regs *,long );extern void show_stack_regs (struct pt_regs *regs);
arch/x86/kernel/dumpstack.c +4 -14
@@ -46,14 +46,7 @@ static void printk_stack_address(unsigned long address, int reliable, char *log_lvl) {touch_nmi_watchdog (); -printk ("%s [<%p>] %s%pB\n" , - log_lvl, (void *)address, reliable ?"" :"? " , - (void *)address); -} - -void printk_address (unsigned long address) -{ -pr_cont (" [<%p>] %pS\n" , (void *)address, (void *)address); +printk ("%s %s%pB\n" , log_lvl, reliable ?"" :"? " , (void *)address); } void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
@@ -275,14 +268,11 @@ int __die(const char *str, struct pt_regs *regs, long err) sp =kernel_stack_pointer (regs); savesegment(ss, ss); } -printk (KERN_EMERG "EIP: [<%08lx>] " , regs->ip); -print_symbol ("%s" , regs->ip); -printk (" SS:ESP %04x:%08lx\n" , ss, sp); +printk (KERN_EMERG "EIP: %pS SS:ESP: %04x:%08lx\n" , + (void *)regs->ip, ss, sp);#else /* Executive summary in case the oops scrolled away */ -printk (KERN_ALERT "RIP " ); -printk_address (regs->ip); -printk (" RSP <%016lx>\n" , regs->sp); +printk (KERN_ALERT "RIP: %pS RSP: %016lx\n" , (void *)regs->ip, regs->sp);#endif return 0 ; }
arch/x86/kernel/process_32.c +3 -4
@@ -72,10 +72,9 @@ void __show_regs(struct pt_regs *regs, int all)savesegment (gs, gs); } -printk (KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n" , - (u16 )regs->cs, regs->ip, regs->flags, -smp_processor_id ()); -print_symbol ("EIP is at %s\n" , regs->ip); +printk (KERN_DEFAULT "EIP: %pS\n" , (void *)regs->ip); +printk (KERN_DEFAULT "EFLAGS: %08lx CPU: %d\n" , regs->flags, +smp_processor_id ());printk (KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n" , regs->ax, regs->bx, regs->cx, regs->dx);
arch/x86/kernel/process_64.c +3 -3
@@ -61,10 +61,10 @@ void __show_regs(struct pt_regs *regs, int all)unsigned int fsindex, gsindex;unsigned int ds, cs, es; -printk (KERN_DEFAULT "RIP: %04lx:[<%016lx>] %pS\n" , regs->cs &0xffff , - regs->ip, (void *)regs->ip); +printk (KERN_DEFAULT "RIP: %04lx:%pS\n" , regs->cs &0xffff , + (void *)regs->ip);printk (KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx" , regs->ss, - regs->sp, regs->flags); + regs->sp, regs->flags);if (regs->orig_ax !=-1 )pr_cont (" ORIG_RAX: %016lx\n" , regs->orig_ax);else
arch/x86/mm/fault.c +1 -2
@@ -679,8 +679,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,printk (KERN_CONT "paging request" );printk (KERN_CONT " at %p\n" , (void *) address); -printk (KERN_ALERT "IP:" ); -printk_address (regs->ip); +printk (KERN_ALERT "IP: %pS\n" , (void *)regs->ip);dump_pagetable (address); }
arch/x86/platform/uv/uv_nmi.c +2 -2
@@ -387,8 +387,8 @@ static void uv_nmi_dump_cpu_ip_hdr(void)/* Dump Instruction Pointer info */ static void uv_nmi_dump_cpu_ip (int cpu,struct pt_regs *regs) { -pr_info ("UV: %4d %6d %-32.32s " , cpu, current->pid, current->comm); -printk_address (regs->ip); +pr_info ("UV: %4d %6d %-32.32s %pS" , + cpu, current->pid, current->comm, (void *)regs->ip); }/*
Signature · 1 line
2.7.4
tip-bot for Josh Poimboeuf
merge bot[tip:x86/asm] x86/dumpstack: Remove kernel text addresses from stack dump
x86/dumpstack: Remove kernel text addresses from stack dump
Commit-ID: bb5e5ce545f2031c96f7901cd8d1698ea3ca4c9c Gitweb: http://git.kernel.org/tip/bb5e5ce545f2031c96f7901cd8d1698ea3ca4c9c Author: Josh Poimboeuf <[email protected]> AuthorDate: Tue, 25 Oct 2016 09:51:12 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 25 Oct 2016 18:40:37 +0200
x86/dumpstack: Remove kernel text addresses from stack dump
Printing kernel text addresses in stack dumps is of questionable value, especially now that address randomization is becoming common.
It can be a security issue because it leaks kernel addresses. It also affects the usefulness of the stack dump. Linus says:
"I actually spend time cleaning up commit messages in logs, because useless data that isn't actually information (random hex numbers) is actively detrimental.
It makes commit logs less legible.
It also makes it harder to parse dumps.
It's not useful. That makes it actively bad.
I probably look at more oops reports than most people. I have not found the hex numbers useful for the last five years, because they are just randomized crap.
The stack content thing just makes code scroll off the screen etc, for example."
The only real downside to removing these addresses is that they can be used to disambiguate duplicate symbol names. However such cases are rare, and the context of the stack dump should be enough to be able to figure it out.
There's now a 'faddr2line' script which can be used to convert a function address to a file name and line:
$ ./scripts/faddr2line ~/k/vmlinux write_sysrq_trigger+0x51/0x60 write_sysrq_trigger+0x51/0x60: write_sysrq_trigger at drivers/tty/sysrq.c:1098
Or gdb can be used:
$ echo "list *write_sysrq_trigger+0x51" |gdb ~/k/vmlinux |grep "is in" (gdb) 0xffffffff815b5d83 is in driver_probe_device (/home/jpoimboe/git/linux/drivers/base/dd.c:378).
(But note that when there are duplicate symbol names, gdb will only show the first symbol it finds. faddr2line is recommended over gdb because it handles duplicates and it also does function size checking.)
Here's an example of what a stack dump looks like after this change:
BUG: unable to handle kernel NULL pointer dereference at (null) IP: sysrq_handle_crash+0x45/0x80 PGD 36bfa067 [ 29.650644] PUD 7aca3067 Oops: 0002 [#1] PREEMPT SMP Modules linked in: ... CPU: 1 PID: 786 Comm: bash Tainted: G E 4.9.0-rc1+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.1-1.fc24 04/01/2014 task: ffff880078582a40 task.stack: ffffc90000ba8000 RIP: 0010:sysrq_handle_crash+0x45/0x80 RSP: 0018:ffffc90000babdc8 EFLAGS: 00010296 RAX: ffff880078582a40 RBX: 0000000000000063 RCX: 0000000000000001 RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000292 RBP: ffffc90000babdc8 R08: 0000000b31866061 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000007 R14: ffffffff81ee8680 R15: 0000000000000000 FS: 00007ffb43869700(0000) GS:ffff88007d400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000007a3e9000 CR4: 00000000001406e0 Stack: ffffc90000babe00 ffffffff81572d08 ffffffff81572bd5 0000000000000002 0000000000000000 ffff880079606600 00007ffb4386e000 ffffc90000babe20 ffffffff81573201 ffff880036a3fd00 fffffffffffffffb ffffc90000babe40 Call Trace: __handle_sysrq+0x138/0x220 ? __handle_sysrq+0x5/0x220 write_sysrq_trigger+0x51/0x60 proc_reg_write+0x42/0x70 __vfs_write+0x37/0x140 ? preempt_count_sub+0xa1/0x100 ? __sb_start_write+0xf5/0x210 ? vfs_write+0x183/0x1a0 vfs_write+0xb8/0x1a0 SyS_write+0x58/0xc0 entry_SYSCALL_64_fastpath+0x1f/0xc2 RIP: 0033:0x7ffb42f55940 RSP: 002b:00007ffd33bb6b18 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000046 RCX: 00007ffb42f55940 RDX: 0000000000000002 RSI: 00007ffb4386e000 RDI: 0000000000000001 RBP: 0000000000000011 R08: 00007ffb4321ea40 R09: 00007ffb43869700 R10: 00007ffb43869700 R11: 0000000000000246 R12: 0000000000778a10 R13: 00007ffd33bb5c00 R14: 0000000000000007 R15: 0000000000000010 Code: 34 e8 d0 34 bc ff 48 c7 c2 3b 2b 57 81 be 01 00 00 00 48 c7 c7 e0 dd e5 81 e8 a8 55 ba ff c7 05 0e 3f de 00 01 00 00 00 0f ae f8 <c6> 04 25 00 00 00 00 01 5d c3 e8 4c 49 bc ff 84 c0 75 c3 48 c7 RIP: sysrq_handle_crash+0x45/0x80 RSP: ffffc90000babdc8 CR2: 0000000000000000
--- arch/x86/include/asm/kdebug.h | 1 - arch/x86/kernel/dumpstack.c | 18 ++++-------------- arch/x86/kernel/process_32.c | 7 +++---- arch/x86/kernel/process_64.c | 6 +++--- arch/x86/mm/fault.c | 3 +-- arch/x86/platform/uv/uv_nmi.c | 4 ++-- 6 files changed, 13 insertions(+), 26 deletions(-)
arch/x86/include/asm/kdebug.h +0 -1
@@ -21,7 +21,6 @@ enum die_val { DIE_NMIUNKNOWN, }; -extern void printk_address (unsigned long address);extern void die (const char *,struct pt_regs *,long );extern int __must_check __die (const char *,struct pt_regs *,long );extern void show_stack_regs (struct pt_regs *regs);
arch/x86/kernel/dumpstack.c +4 -14
@@ -46,14 +46,7 @@ static void printk_stack_address(unsigned long address, int reliable, char *log_lvl) {touch_nmi_watchdog (); -printk ("%s [<%p>] %s%pB\n" , - log_lvl, (void *)address, reliable ?"" :"? " , - (void *)address); -} - -void printk_address (unsigned long address) -{ -pr_cont (" [<%p>] %pS\n" , (void *)address, (void *)address); +printk ("%s %s%pB\n" , log_lvl, reliable ?"" :"? " , (void *)address); } void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
@@ -275,14 +268,11 @@ int __die(const char *str, struct pt_regs *regs, long err) sp =kernel_stack_pointer (regs); savesegment(ss, ss); } -printk (KERN_EMERG "EIP: [<%08lx>] " , regs->ip); -print_symbol ("%s" , regs->ip); -printk (" SS:ESP %04x:%08lx\n" , ss, sp); +printk (KERN_EMERG "EIP: %pS SS:ESP: %04x:%08lx\n" , + (void *)regs->ip, ss, sp);#else /* Executive summary in case the oops scrolled away */ -printk (KERN_ALERT "RIP " ); -printk_address (regs->ip); -printk (" RSP <%016lx>\n" , regs->sp); +printk (KERN_ALERT "RIP: %pS RSP: %016lx\n" , (void *)regs->ip, regs->sp);#endif return 0 ; }
arch/x86/kernel/process_32.c +3 -4
@@ -72,10 +72,9 @@ void __show_regs(struct pt_regs *regs, int all)savesegment (gs, gs); } -printk (KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n" , - (u16 )regs->cs, regs->ip, regs->flags, -smp_processor_id ()); -print_symbol ("EIP is at %s\n" , regs->ip); +printk (KERN_DEFAULT "EIP: %pS\n" , (void *)regs->ip); +printk (KERN_DEFAULT "EFLAGS: %08lx CPU: %d\n" , regs->flags, +smp_processor_id ());printk (KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n" , regs->ax, regs->bx, regs->cx, regs->dx);
arch/x86/kernel/process_64.c +3 -3
@@ -61,10 +61,10 @@ void __show_regs(struct pt_regs *regs, int all)unsigned int fsindex, gsindex;unsigned int ds, cs, es; -printk (KERN_DEFAULT "RIP: %04lx:[<%016lx>] %pS\n" , regs->cs &0xffff , - regs->ip, (void *)regs->ip); +printk (KERN_DEFAULT "RIP: %04lx:%pS\n" , regs->cs &0xffff , + (void *)regs->ip);printk (KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx" , regs->ss, - regs->sp, regs->flags); + regs->sp, regs->flags);if (regs->orig_ax !=-1 )pr_cont (" ORIG_RAX: %016lx\n" , regs->orig_ax);else
arch/x86/mm/fault.c +1 -2
@@ -679,8 +679,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,printk (KERN_CONT "paging request" );printk (KERN_CONT " at %p\n" , (void *) address); -printk (KERN_ALERT "IP:" ); -printk_address (regs->ip); +printk (KERN_ALERT "IP: %pS\n" , (void *)regs->ip);dump_pagetable (address); }
arch/x86/platform/uv/uv_nmi.c +2 -2
@@ -387,8 +387,8 @@ static void uv_nmi_dump_cpu_ip_hdr(void)/* Dump Instruction Pointer info */ static void uv_nmi_dump_cpu_ip (int cpu,struct pt_regs *regs) { -pr_info ("UV: %4d %6d %-32.32s " , cpu, current->pid, current->comm); -printk_address (regs->ip); +pr_info ("UV: %4d %6d %-32.32s %pS" , + cpu, current->pid, current->comm, (void *)regs->ip); }/*
Re: [PATCH 2/4] x86/dumpstack: remove kernel text addresses from stack dump
In reply to Josh PoimboeufQuoted 35 lines · Josh Poimboeuf
Printing kernel text addresses in stack dumps is of questionable value, especially now that address randomization is becoming common.
It can be a security issue because it leaks kernel addresses. It also affects the usefulness of the stack dump. Linus says:
"I actually spend time cleaning up commit messages in logs, because useless data that isn't actually information (random hex numbers) is actively detrimental.
It makes commit logs less legible.
It also makes it harder to parse dumps.
It's not useful. That makes it actively bad.
I probably look at more oops reports than most people. I have not found the hex numbers useful for the last five years, because they are just randomized crap.
The stack content thing just makes code scroll off the screen etc, for example."
The only real downside to removing these addresses is that they can be used to disambiguate duplicate symbol names. However such cases are rare, and the context of the stack dump should be enough to be able to figure it out.
There's now a 'faddr2line' script which can be used to convert a function address to a file name and line:
$ ./scripts/faddr2line ~/k/vmlinux write_sysrq_trigger+0x51/0x60 write_sysrq_trigger+0x51/0x60: write_sysrq_trigger at drivers/tty/sysrq.c:1098
Quoted 8 lines
Or gdb can be used:
$ echo "list *write_sysrq_trigger+0x51" |gdb ~/k/vmlinux |grep "is in" (gdb) 0xffffffff815b5d83 is in driver_probe_device (/home/jpoimboe/git/linux/drivers/base/dd.c:378).(But note that when there are duplicate symbol names, gdb will only show the first symbol it finds. faddr2line is recommended over gdb because it handles duplicates and it also does function size checking.)
The commit breaks scripts/decode_stacktrace.sh.
Not sure if it's possible to fix it only on decode_stacktrace.sh side: we seems don't have a way to clearly distinguish stack trace line of any other.
May be we should mark stack lines with some prefix to simplify decoding?
Signature · 1 line
Kirill A. Shutemov
Re: [PATCH 2/4] x86/dumpstack: remove kernel text addresses from stack dump
Quoted 45 lines · Kirill A. Shutemov
Quoted 35 lines · Josh Poimboeuf
Printing kernel text addresses in stack dumps is of questionable value, especially now that address randomization is becoming common.
It can be a security issue because it leaks kernel addresses. It also affects the usefulness of the stack dump. Linus says:
"I actually spend time cleaning up commit messages in logs, because useless data that isn't actually information (random hex numbers) is actively detrimental.
It makes commit logs less legible.
It also makes it harder to parse dumps.
It's not useful. That makes it actively bad.
I probably look at more oops reports than most people. I have not found the hex numbers useful for the last five years, because they are just randomized crap.
The stack content thing just makes code scroll off the screen etc, for example."
The only real downside to removing these addresses is that they can be used to disambiguate duplicate symbol names. However such cases are rare, and the context of the stack dump should be enough to be able to figure it out.
There's now a 'faddr2line' script which can be used to convert a function address to a file name and line:
$ ./scripts/faddr2line ~/k/vmlinux write_sysrq_trigger+0x51/0x60 write_sysrq_trigger+0x51/0x60: write_sysrq_trigger at drivers/tty/sysrq.c:1098Quoted 8 lines
Or gdb can be used:
$ echo "list *write_sysrq_trigger+0x51" |gdb ~/k/vmlinux |grep "is in" (gdb) 0xffffffff815b5d83 is in driver_probe_device (/home/jpoimboe/git/linux/drivers/base/dd.c:378).(But note that when there are duplicate symbol names, gdb will only show the first symbol it finds. faddr2line is recommended over gdb because it handles duplicates and it also does function size checking.)
Quoted 5 lines
The commit breaks
scripts/decode_stacktrace.sh.Not sure if it's possible to fix it only on
decode_stacktrace.shside: we seems don't have a way to clearly distinguish stack trace line of any other.
How about this bash regex? Seems to work for me with no false positives.
[[ $line =~ [^+\ ]+\+0x[0-9a-f]+/0x[0-9a-f]+ ]]
Signature · 1 line
Josh
Re: [PATCH 2/4] x86/dumpstack: remove kernel text addresses from stack dump
Quoted 48 lines · Josh Poimboeuf
Quoted 47 lines · Kirill A. Shutemov
Quoted 35 lines · Josh Poimboeuf
Printing kernel text addresses in stack dumps is of questionable value, especially now that address randomization is becoming common.
It can be a security issue because it leaks kernel addresses. It also affects the usefulness of the stack dump. Linus says:
"I actually spend time cleaning up commit messages in logs, because useless data that isn't actually information (random hex numbers) is actively detrimental.
It makes commit logs less legible.
It also makes it harder to parse dumps.
It's not useful. That makes it actively bad.
I probably look at more oops reports than most people. I have not found the hex numbers useful for the last five years, because they are just randomized crap.
The stack content thing just makes code scroll off the screen etc, for example."
The only real downside to removing these addresses is that they can be used to disambiguate duplicate symbol names. However such cases are rare, and the context of the stack dump should be enough to be able to figure it out.
There's now a 'faddr2line' script which can be used to convert a function address to a file name and line:
$ ./scripts/faddr2line ~/k/vmlinux write_sysrq_trigger+0x51/0x60 write_sysrq_trigger+0x51/0x60: write_sysrq_trigger at drivers/tty/sysrq.c:1098Quoted 8 lines
Or gdb can be used:
$ echo "list *write_sysrq_trigger+0x51" |gdb ~/k/vmlinux |grep "is in" (gdb) 0xffffffff815b5d83 is in driver_probe_device (/home/jpoimboe/git/linux/drivers/base/dd.c:378).(But note that when there are duplicate symbol names, gdb will only show the first symbol it finds. faddr2line is recommended over gdb because it handles duplicates and it also does function size checking.)
The commit breaks
scripts/decode_stacktrace.sh.
Quoted 8 lines
Quoted 3 lines
Not sure if it's possible to fix it only on
decode_stacktrace.shside: we seems don't have a way to clearly distinguish stack trace line of any other.How about this bash regex? Seems to work for me with no false positives.
[[ $line =~ [^+\ ]+\+0x[0-9a-f]+/0x[0-9a-f]+ ]]
Seems works fine to me. Thanks.
Feel free to use my tested-by.
Signature · 1 line
Kirill A. Shutemov
PATCH 1/1 decode_stacktrace: fix address line detection on x86
Kirill reported that the decode_stacktrace.sh script was broken by the following commit:
bb5e5ce545f2 ("x86/dumpstack: Remove kernel text addresses from stack dump")
Fix it by updating the per-line absolute address check to also check for function-based address lines like the following:
write_sysrq_trigger+0x51/0x60
I didn't remove the check for absolute addresses because it's still needed for ARM.
--- scripts/decode_stacktrace.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/decode_stacktrace.sh +2 -1
@@ -139,7 +139,8 @@ handle_line() { while read line; do # Let's see if we have an address in the line - if [[ $line =~ \[\<([^]]+)\>\] ]]; then + if [[ $line =~ \[\<([^]]+)\>\] ]] || + [[ $line =~ [^+\ ]+\+0x[0-9a-f]+/0x[0-9a-f]+ ]]; then # Translate address to line numbers handle_line "$line" # Is it a code line?
Signature · 1 line
2.7.4
tip-bot for Josh Poimboeuf
merge bot[tip:x86/urgent] tools/decode_stacktrace.sh: Fix address line detection on x86
tools/decode_stacktrace.sh: Fix address line detection on x86
Commit-ID: 8e8d8725d46d93ceffd3e708d905bc101a1905b5 Gitweb: http://git.kernel.org/tip/8e8d8725d46d93ceffd3e708d905bc101a1905b5 Author: Josh Poimboeuf <[email protected]> AuthorDate: Mon, 28 Nov 2016 17:06:35 -0600 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Nov 2016 08:10:05 +0100
tools/decode_stacktrace.sh: Fix address line detection on x86
Kirill reported that the decode_stacktrace.sh script was broken by the following commit:
bb5e5ce545f2 ("x86/dumpstack: Remove kernel text addresses from stack dump")
Fix it by updating the per-line absolute address check to also check for function-based address lines like the following:
write_sysrq_trigger+0x51/0x60
I didn't remove the check for absolute addresses because it's still needed for ARM.
--- scripts/decode_stacktrace.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/decode_stacktrace.sh +2 -1
@@ -139,7 +139,8 @@ handle_line() { while read line; do # Let's see if we have an address in the line - if [[ $line =~ \[\<([^]]+)\>\] ]]; then + if [[ $line =~ \[\<([^]]+)\>\] ]] || + [[ $line =~ [^+\ ]+\+0x[0-9a-f]+/0x[0-9a-f]+ ]]; then # Translate address to line numbers handle_line "$line" # Is it a code line?
Re: [tip:x86/urgent] tools/decode_stacktrace.sh: Fix address line detection on x86
Hi tip-bot,
Quoted 8 lines · tip-bot for Josh Poimboeuf
Commit-ID: 8e8d8725d46d93ceffd3e708d905bc101a1905b5 Gitweb: http://git.kernel.org/tip/8e8d8725d46d93ceffd3e708d905bc101a1905b5 Author: Josh Poimboeuf <[email protected]> AuthorDate: Mon, 28 Nov 2016 17:06:35 -0600 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Nov 2016 08:10:05 +0100
tools/decode_stacktrace.sh: Fix address line detection on x86
It's actually in the scripts subdir, so: s/tools/scripts/
Also, while it should be harmless for this to be in 'urgent', I think it isn't necessary because it fixes a commit which is currently only in tip.
Signature · 1 line
Josh
Re: [tip:x86/urgent] tools/decode_stacktrace.sh: Fix address line detection on x86
Quoted 10 lines · Josh Poimboeuf
Hi tip-bot,
Quoted 7 lines · tip-bot for Josh Poimboeuf
Commit-ID: 8e8d8725d46d93ceffd3e708d905bc101a1905b5 Gitweb: http://git.kernel.org/tip/8e8d8725d46d93ceffd3e708d905bc101a1905b5 Author: Josh Poimboeuf <[email protected]> AuthorDate: Mon, 28 Nov 2016 17:06:35 -0600 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Nov 2016 08:10:05 +0100
Quoted 3 lines
Quoted 1 line
tools/decode_stacktrace.sh: Fix address line detection on x86It's actually in the scripts subdir, so: s/tools/scripts/
So that was conscious - it might be in 'scripts' but it is really a tool!
No strong feelings either way.
Quoted 3 lines
Also, while it should be harmless for this to be in 'urgent', I think it isn't necessary because it fixes a commit which is currently only in tip.
I missed that.
Ok, I rebased it over into tip:x86/asm and fixed the title as well while at it.
Thanks,
Ingo
tip-bot for Josh Poimboeuf
merge bot[tip:x86/asm] scripts/decode_stacktrace.sh: Fix address line detection on x86
In reply to Josh Poimboeufscripts/decode_stacktrace.sh: Fix address line detection on x86
Commit-ID: 53938ee427bf27525a63721b7e25d86b8f31f161 Gitweb: http://git.kernel.org/tip/53938ee427bf27525a63721b7e25d86b8f31f161 Author: Josh Poimboeuf <[email protected]> AuthorDate: Mon, 28 Nov 2016 17:06:35 -0600 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Nov 2016 14:19:50 +0100
scripts/decode_stacktrace.sh: Fix address line detection on x86
Kirill reported that the decode_stacktrace.sh script was broken by the following commit:
bb5e5ce545f2 ("x86/dumpstack: Remove kernel text addresses from stack dump")
Fix it by updating the per-line absolute address check to also check for function-based address lines like the following:
write_sysrq_trigger+0x51/0x60
I didn't remove the check for absolute addresses because it's still needed for ARM.
--- scripts/decode_stacktrace.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/decode_stacktrace.sh +2 -1
@@ -139,7 +139,8 @@ handle_line() { while read line; do # Let's see if we have an address in the line - if [[ $line =~ \[\<([^]]+)\>\] ]]; then + if [[ $line =~ \[\<([^]]+)\>\] ]] || + [[ $line =~ [^+\ ]+\+0x[0-9a-f]+/0x[0-9a-f]+ ]]; then # Translate address to line numbers handle_line "$line" # Is it a code line?
PATCH 3/4 x86/dumpstack: remove raw stack dump
In reply to Josh PoimboeufFor mostly historical reasons, the x86 oops dump shows the raw stack values:
...
[registers]
Stack: ffff880079af7350 ffff880079905400 0000000000000000 ffffc900008f3ae0 ffffffffa0196610 0000000000000001 00010000ffffffff 0000000087654321 0000000000000002 0000000000000000 0000000000000000 0000000000000000 Call Trace: ...
This seems to be an artifact from long ago, and probably isn't needed anymore. It generally just adds noise to the dump, and it can be actively harmful because it leaks kernel addresses.
Linus says:
"The stack dump actually goes back to forever, and it used to be
useful back in 1992 or so. But it used to be useful mainly because stacks were simpler and we didn't have very good call traces anyway. I definitely remember having used them - I just do not remember having used them in the last ten+ years.
Of course, it's still true that if you can trigger an oops, you've likely already lost the security game, but since the stack dump is so useless, let's aim to just remove it and make games like the above harder."
This also removes the related 'kstack=' cmdline option and the 'kstack_depth_to_print' sysctl.
--- Documentation/kernel-parameters.txt | 3 -- Documentation/sysctl/kernel.txt | 8 ----- Documentation/x86/x86_64/boot-options.txt | 4 --- arch/x86/include/asm/stacktrace.h | 5 --- arch/x86/kernel/dumpstack.c | 21 ++---------- arch/x86/kernel/dumpstack_32.c | 33 +------------------ arch/x86/kernel/dumpstack_64.c | 53 +------------------------------ kernel/sysctl.c | 7 ---- 8 files changed, 4 insertions(+), 130 deletions(-)
Documentation/kernel-parameters.txt +0 -3
@@ -1952,9 +1952,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. kmemcheck=2 (one-shot mode) Default: 2 (one-shot mode) - kstack=N [X86] Print N words from the kernel stack - in oops dumps. - kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. Default is 0 (don't ignore, but inject #GP)
Documentation/sysctl/kernel.txt +0 -8
@@ -40,7 +40,6 @@ show up in /proc/sys/kernel: - hung_task_warnings - kexec_load_disabled - kptr_restrict -- kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] - modprobe ==> Documentation/debugging-modules.txt - modules_disabled
@@ -395,13 +394,6 @@ When kptr_restrict is set to (2), kernel pointers printed using ============================================================== -kstack_depth_to_print: (X86 only) - -Controls the number of words to print when dumping the raw -kernel stack. - -============================================================== - l2cr: (PPC only) This flag controls the L2 cache of G3 processor boards. If
Documentation/x86/x86_64/boot-options.txt +0 -4
@@ -277,10 +277,6 @@ IOMMU (input/output memory management unit) space might stop working. Use this option if you have devices that are accessed from userspace directly on some PCI host bridge. -Debugging - - kstack=N Print N words from the kernel stack in oops dumps. - Miscellaneous nogbpages
arch/x86/include/asm/stacktrace.h +0 -5
@@ -43,8 +43,6 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len) addr + len > begin && addr + len <= end); } -extern int kstack_depth_to_print; -#ifdef CONFIG_X86_32 #define STACKSLOTS_PER_LINE 8#else
@@ -86,9 +84,6 @@ get_stack_pointer(struct task_struct *task, struct pt_regs *regs)void show_trace_log_lvl (struct task_struct *task,struct pt_regs *regs,unsigned long *stack,char *log_lvl); -void show_stack_log_lvl (struct task_struct *task,struct pt_regs *regs, -unsigned long *sp,char *log_lvl); -extern unsigned int code_bytes;/* The form of the top of the frame on the stack */
arch/x86/kernel/dumpstack.c +2 -19
@@ -22,7 +22,6 @@int panic_on_unrecovered_nmi;int panic_on_io_nmi;unsigned int code_bytes =64 ; -int kstack_depth_to_print =3 *STACKSLOTS_PER_LINE ;static int die_counter; bool in_task_stack(unsigned long *stack, struct task_struct *task,
@@ -171,12 +170,12 @@ void show_stack(struct task_struct *task, unsigned long *sp)if (!sp && task == current) sp =get_stack_pointer (current,NULL ); -show_stack_log_lvl (task,NULL , sp,KERN_DEFAULT ); +show_trace_log_lvl (task,NULL , sp,KERN_DEFAULT ); }void show_stack_regs (struct pt_regs *regs) { -show_stack_log_lvl (current, regs,NULL ,KERN_DEFAULT ); +show_trace_log_lvl (current, regs,NULL ,KERN_DEFAULT ); }static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
@@ -295,22 +294,6 @@ void die(const char *str, struct pt_regs *regs, long err)oops_end (flags, regs, sig); } -static int __init kstack_setup (char *s) -{ -ssize_t ret; -unsigned long val; - -if (!s) -return -EINVAL ; - - ret =kstrtoul (s,0 , &val); -if (ret) -return ret; - kstack_depth_to_print = val; -return 0 ; -} -early_param ("kstack" , kstack_setup); -static int __init code_bytes_setup (char *s) {ssize_t ret;
arch/x86/kernel/dumpstack_32.c +1 -32
@@ -121,36 +121,6 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,return -EINVAL ; } -void show_stack_log_lvl (struct task_struct *task,struct pt_regs *regs, -unsigned long *sp,char *log_lvl) -{ -unsigned long *stack; -int i; - -if (!try_get_task_stack (task)) -return ; - - sp = sp ? :get_stack_pointer (task, regs); - - stack = sp; -for (i =0 ; i < kstack_depth_to_print; i++) { -if (kstack_end (stack)) -break ; -if ((i %STACKSLOTS_PER_LINE ) ==0 ) { -if (i !=0 ) -pr_cont ("\n" ); -printk ("%s %08lx" , log_lvl, *stack++); - }else -pr_cont (" %08lx" , *stack++); -touch_nmi_watchdog (); - } -pr_cont ("\n" ); -show_trace_log_lvl (task, regs, sp, log_lvl); - -put_task_stack (task); -} - -void show_regs (struct pt_regs *regs) {int i;
@@ -168,8 +138,7 @@ void show_regs(struct pt_regs *regs)unsigned char c;u8 *ip; -pr_emerg ("Stack:\n" ); -show_stack_log_lvl (current, regs,NULL ,KERN_EMERG ); +show_trace_log_lvl (current, regs,NULL ,KERN_EMERG );pr_emerg ("Code:" );
arch/x86/kernel/dumpstack_64.c +1 -52
65 lines not on this page · raw message
kernel/sysctl.c +0 -7
@@ -983,13 +983,6 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, { - .procname = "kstack_depth_to_print", - .data = &kstack_depth_to_print, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec, - }, - { .procname = "io_delay_type", .data = &io_delay_type, .maxlen = sizeof(int),
Signature · 1 line
2.7.4
tip-bot for Josh Poimboeuf
merge bot[tip:x86/asm] x86/dumpstack: Remove raw stack dump
x86/dumpstack: Remove raw stack dump
Commit-ID: 0ee1dd9f5e7eae4e55f95935b72d4beecb03de9c Gitweb: http://git.kernel.org/tip/0ee1dd9f5e7eae4e55f95935b72d4beecb03de9c Author: Josh Poimboeuf <[email protected]> AuthorDate: Tue, 25 Oct 2016 09:51:13 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 25 Oct 2016 18:40:37 +0200
x86/dumpstack: Remove raw stack dump
For mostly historical reasons, the x86 oops dump shows the raw stack values:
...
[registers]
Stack: ffff880079af7350 ffff880079905400 0000000000000000 ffffc900008f3ae0 ffffffffa0196610 0000000000000001 00010000ffffffff 0000000087654321 0000000000000002 0000000000000000 0000000000000000 0000000000000000 Call Trace: ...
This seems to be an artifact from long ago, and probably isn't needed anymore. It generally just adds noise to the dump, and it can be actively harmful because it leaks kernel addresses.
Linus says:
"The stack dump actually goes back to forever, and it used to be
useful back in 1992 or so. But it used to be useful mainly because stacks were simpler and we didn't have very good call traces anyway. I definitely remember having used them - I just do not remember having used them in the last ten+ years.
Of course, it's still true that if you can trigger an oops, you've likely already lost the security game, but since the stack dump is so useless, let's aim to just remove it and make games like the above harder."
This also removes the related 'kstack=' cmdline option and the 'kstack_depth_to_print' sysctl.
--- Documentation/kernel-parameters.txt | 3 -- Documentation/sysctl/kernel.txt | 8 ----- Documentation/x86/x86_64/boot-options.txt | 4 --- arch/x86/include/asm/stacktrace.h | 5 --- arch/x86/kernel/dumpstack.c | 21 ++---------- arch/x86/kernel/dumpstack_32.c | 33 +------------------ arch/x86/kernel/dumpstack_64.c | 53 +------------------------------ kernel/sysctl.c | 7 ---- 8 files changed, 4 insertions(+), 130 deletions(-)
Documentation/kernel-parameters.txt +0 -3
@@ -1958,9 +1958,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. kmemcheck=2 (one-shot mode) Default: 2 (one-shot mode) - kstack=N [X86] Print N words from the kernel stack - in oops dumps. - kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. Default is 0 (don't ignore, but inject #GP)
Documentation/sysctl/kernel.txt +0 -8
@@ -40,7 +40,6 @@ show up in /proc/sys/kernel: - hung_task_warnings - kexec_load_disabled - kptr_restrict -- kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] - modprobe ==> Documentation/debugging-modules.txt - modules_disabled
@@ -395,13 +394,6 @@ When kptr_restrict is set to (2), kernel pointers printed using ============================================================== -kstack_depth_to_print: (X86 only) - -Controls the number of words to print when dumping the raw -kernel stack. - -============================================================== - l2cr: (PPC only) This flag controls the L2 cache of G3 processor boards. If
Documentation/x86/x86_64/boot-options.txt +0 -4
@@ -277,10 +277,6 @@ IOMMU (input/output memory management unit) space might stop working. Use this option if you have devices that are accessed from userspace directly on some PCI host bridge. -Debugging - - kstack=N Print N words from the kernel stack in oops dumps. - Miscellaneous nogbpages
arch/x86/include/asm/stacktrace.h +0 -5
@@ -43,8 +43,6 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len) addr + len > begin && addr + len <= end); } -extern int kstack_depth_to_print; -#ifdef CONFIG_X86_32 #define STACKSLOTS_PER_LINE 8#else
@@ -86,9 +84,6 @@ get_stack_pointer(struct task_struct *task, struct pt_regs *regs)void show_trace_log_lvl (struct task_struct *task,struct pt_regs *regs,unsigned long *stack,char *log_lvl); -void show_stack_log_lvl (struct task_struct *task,struct pt_regs *regs, -unsigned long *sp,char *log_lvl); -extern unsigned int code_bytes;/* The form of the top of the frame on the stack */
arch/x86/kernel/dumpstack.c +2 -19
@@ -22,7 +22,6 @@int panic_on_unrecovered_nmi;int panic_on_io_nmi;unsigned int code_bytes =64 ; -int kstack_depth_to_print =3 *STACKSLOTS_PER_LINE ;static int die_counter; bool in_task_stack(unsigned long *stack, struct task_struct *task,
@@ -171,12 +170,12 @@ void show_stack(struct task_struct *task, unsigned long *sp)if (!sp && task == current) sp =get_stack_pointer (current,NULL ); -show_stack_log_lvl (task,NULL , sp,KERN_DEFAULT ); +show_trace_log_lvl (task,NULL , sp,KERN_DEFAULT ); }void show_stack_regs (struct pt_regs *regs) { -show_stack_log_lvl (current, regs,NULL ,KERN_DEFAULT ); +show_trace_log_lvl (current, regs,NULL ,KERN_DEFAULT ); }static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
@@ -295,22 +294,6 @@ void die(const char *str, struct pt_regs *regs, long err)oops_end (flags, regs, sig); } -static int __init kstack_setup (char *s) -{ -ssize_t ret; -unsigned long val; - -if (!s) -return -EINVAL ; - - ret =kstrtoul (s,0 , &val); -if (ret) -return ret; - kstack_depth_to_print = val; -return 0 ; -} -early_param ("kstack" , kstack_setup); -static int __init code_bytes_setup (char *s) {ssize_t ret;
arch/x86/kernel/dumpstack_32.c +1 -32
@@ -121,36 +121,6 @@ unknown:return -EINVAL ; } -void show_stack_log_lvl (struct task_struct *task,struct pt_regs *regs, -unsigned long *sp,char *log_lvl) -{ -unsigned long *stack; -int i; - -if (!try_get_task_stack (task)) -return ; - - sp = sp ? :get_stack_pointer (task, regs); - - stack = sp; -for (i =0 ; i < kstack_depth_to_print; i++) { -if (kstack_end (stack)) -break ; -if ((i %STACKSLOTS_PER_LINE ) ==0 ) { -if (i !=0 ) -pr_cont ("\n" ); -printk ("%s %08lx" , log_lvl, *stack++); - }else -pr_cont (" %08lx" , *stack++); -touch_nmi_watchdog (); - } -pr_cont ("\n" ); -show_trace_log_lvl (task, regs, sp, log_lvl); - -put_task_stack (task); -} - -void show_regs (struct pt_regs *regs) {int i;
@@ -168,8 +138,7 @@ void show_regs(struct pt_regs *regs)unsigned char c;u8 *ip; -pr_emerg ("Stack:\n" ); -show_stack_log_lvl (current, regs,NULL ,KERN_EMERG ); +show_trace_log_lvl (current, regs,NULL ,KERN_EMERG );pr_emerg ("Code:" );
arch/x86/kernel/dumpstack_64.c +1 -52
65 lines not on this page · raw message
kernel/sysctl.c +0 -7
@@ -990,13 +990,6 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, { - .procname = "kstack_depth_to_print", - .data = &kstack_depth_to_print, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec, - }, - { .procname = "io_delay_type", .data = &io_delay_type, .maxlen = sizeof(int),
PATCH 4/4 mm: remove kernel address exposure in free_reserved_area()
In reply to Josh PoimboeufLinus suggested we try to remove some of the low-hanging fruit related to kernel address exposure in dmesg. The only leaks I see on my local system are:
Freeing SMP alternatives memory: 32K (ffffffff9e309000 - ffffffff9e311000) Freeing initrd memory: 10588K (ffffa0b736b42000 - ffffa0b737599000) Freeing unused kernel memory: 3592K (ffffffff9df87000 - ffffffff9e309000) Freeing unused kernel memory: 1352K (ffffa0b7288ae000 - ffffa0b728a00000) Freeing unused kernel memory: 632K (ffffa0b728d62000 - ffffa0b728e00000)
Linus says:
"I suspect we should just remove [the addresses in the 'Freeing'
messages]. I'm sure they are useful in theory, but I suspect they were more useful back when the whole "free init memory" was originally done.
These days, if we have a use-after-free, I suspect the init-mem situation is the easiest situation by far. Compared to all the dynamic allocations which are much more likely to show it anyway. So having debug output for that case is likely not all that productive."
With this patch the freeing messages now look like this:
Freeing SMP alternatives memory: 32K
Freeing initrd memory: 10588K
Freeing unused kernel memory: 3592K
Freeing unused kernel memory: 1352K
Freeing unused kernel memory: 632K
--- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page_alloc.c +2 -2
@@ -6508,8 +6508,8 @@ unsigned long free_reserved_area(void *start, void *end, int poison, char *s) }if (pages && s) -pr_info ("Freeing %s memory: %ldK (%p - %p)\n" , - s, pages << (PAGE_SHIFT -10 ), start, end); +pr_info ("Freeing %s memory: %ldK\n" , + s, pages << (PAGE_SHIFT -10 ));return pages; }
Signature · 7 lines
2.7.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
tip-bot for Josh Poimboeuf
merge bot[tip:x86/asm] mm/page_alloc: Remove kernel address exposure in free_reserved_area()
mm/page_alloc: Remove kernel address exposure in free_reserved_area()
Commit-ID: adb1fe9ae2ee6ef6bc10f3d5a588020e7664dfa7 Gitweb: http://git.kernel.org/tip/adb1fe9ae2ee6ef6bc10f3d5a588020e7664dfa7 Author: Josh Poimboeuf <[email protected]> AuthorDate: Tue, 25 Oct 2016 09:51:14 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 25 Oct 2016 18:40:37 +0200
mm/page_alloc: Remove kernel address exposure in free_reserved_area()
Linus suggested we try to remove some of the low-hanging fruit related to kernel address exposure in dmesg. The only leaks I see on my local system are:
Freeing SMP alternatives memory: 32K (ffffffff9e309000 - ffffffff9e311000) Freeing initrd memory: 10588K (ffffa0b736b42000 - ffffa0b737599000) Freeing unused kernel memory: 3592K (ffffffff9df87000 - ffffffff9e309000) Freeing unused kernel memory: 1352K (ffffa0b7288ae000 - ffffa0b728a00000) Freeing unused kernel memory: 632K (ffffa0b728d62000 - ffffa0b728e00000)
Linus says:
"I suspect we should just remove [the addresses in the 'Freeing'
messages]. I'm sure they are useful in theory, but I suspect they were more useful back when the whole "free init memory" was originally done.
These days, if we have a use-after-free, I suspect the init-mem situation is the easiest situation by far. Compared to all the dynamic allocations which are much more likely to show it anyway. So having debug output for that case is likely not all that productive."
With this patch the freeing messages now look like this:
Freeing SMP alternatives memory: 32K
Freeing initrd memory: 10588K
Freeing unused kernel memory: 3592K
Freeing unused kernel memory: 1352K
Freeing unused kernel memory: 632K
--- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page_alloc.c +2 -2
@@ -6508,8 +6508,8 @@ unsigned long free_reserved_area(void *start, void *end, int poison, char *s) }if (pages && s) -pr_info ("Freeing %s memory: %ldK (%p - %p)\n" , - s, pages << (PAGE_SHIFT -10 ), start, end); +pr_info ("Freeing %s memory: %ldK\n" , + s, pages << (PAGE_SHIFT -10 ));return pages; }