perf tools: Fix segfault for kernel.kptr_restrict=2
Jiri Olsa
reviewerPATCH 1/1 perf tools: Fix segfault for kernel.kptr_restrict=2
Michael reported the segfault when kernel.kptr_restrict=2 is set.
$ perf record ls ... perf: Segmentation fault Obtained 16 stack frames. ./perf(dump_stack+0x2d) [0x5068df] ./perf(sighandler_dump_stack+0x2d) [0x5069bf] ./perf() [0x43e47b] /lib64/libc.so.6(+0x3594f) [0x7f762004794f] /lib64/libc.so.6(strlen+0x26) [0x7f762009ef86] /lib64/libc.so.6(__strdup+0xd) [0x7f762009ecbd] ./perf(maps__set_kallsyms_ref_reloc_sym+0x4d) [0x51590f] ./perf(machine__create_kernel_maps+0x136) [0x50a7de] ./perf(perf_session__create_kernel_maps+0x2c) [0x510a81] ./perf(perf_session__new+0x13d) [0x510e23] ./perf() [0x43fd61] ./perf(cmd_record+0x704) [0x441823] ./perf() [0x4bc1a0] ./perf() [0x4bc40d] ./perf() [0x4bc55f] ./perf(main+0x2d5) [0x4bc939] Segmentation fault (core dumped)
The reason is that with kernel.kptr_restrict=2, we don't get the symbol from machine__get_running_kernel_start, which we want to use in maps__set_kallsyms_ref_reloc_sym and we crash.
Check the symbol name value before calling maps__set_kallsyms_ref_reloc_sym and succeed without ref_reloc_sym being set. It's safe because we check its existence before we use it.
--- tools/perf/util/machine.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
tools/perf/util/machine.c +6 -4
@@ -1209,10 +1209,12 @@ int machine__create_kernel_maps(struct machine *machine)*/ map_groups__fixup_end (&machine->kmaps); -if (machine__get_running_kernel_start (machine, &name, &addr)) { - }else if (maps__set_kallsyms_ref_reloc_sym (machine->vmlinux_maps, name, addr)) { -machine__destroy_kernel_maps (machine); -return -1 ; +if (!machine__get_running_kernel_start (machine, &name, &addr)) { +if (name && +maps__set_kallsyms_ref_reloc_sym (machine->vmlinux_maps, name, addr)) { +machine__destroy_kernel_maps (machine); +return -1 ; + } }return 0 ;
Signature · 1 line
2.9.4
tip-bot for Jiri Olsa
merge bot[tip:perf/urgent] perf machine: Fix segfault for kernel.kptr_restrict=2
perf machine: Fix segfault for kernel.kptr_restrict=2
Commit-ID: 3f938ee2f6c4fff8d95b24636a0964b5a93cf547 Gitweb: http://git.kernel.org/tip/3f938ee2f6c4fff8d95b24636a0964b5a93cf547 Author: Jiri Olsa <[email protected]> AuthorDate: Mon, 26 Jun 2017 11:51:53 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 26 Jun 2017 11:52:37 -0300
perf machine: Fix segfault for kernel.kptr_restrict=2
Michael reported the segfault when kernel.kptr_restrict=2 is set.
$ perf record ls ... perf: Segmentation fault Obtained 16 stack frames. ./perf(dump_stack+0x2d) [0x5068df] ./perf(sighandler_dump_stack+0x2d) [0x5069bf] ./perf() [0x43e47b] /lib64/libc.so.6(+0x3594f) [0x7f762004794f] /lib64/libc.so.6(strlen+0x26) [0x7f762009ef86] /lib64/libc.so.6(__strdup+0xd) [0x7f762009ecbd] ./perf(maps__set_kallsyms_ref_reloc_sym+0x4d) [0x51590f] ./perf(machine__create_kernel_maps+0x136) [0x50a7de] ./perf(perf_session__create_kernel_maps+0x2c) [0x510a81] ./perf(perf_session__new+0x13d) [0x510e23] ./perf() [0x43fd61] ./perf(cmd_record+0x704) [0x441823] ./perf() [0x4bc1a0] ./perf() [0x4bc40d] ./perf() [0x4bc55f] ./perf(main+0x2d5) [0x4bc939] Segmentation fault (core dumped)
The reason is that with kernel.kptr_restrict=2, we don't get the symbol from machine__get_running_kernel_start, which we want to use in maps__set_kallsyms_ref_reloc_sym and we crash.
Check the symbol name value before calling maps__set_kallsyms_ref_reloc_sym() and succeed without ref_reloc_sym being set. It's safe because we check its existence before we use it.
--- tools/perf/util/machine.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
tools/perf/util/machine.c +6 -4
@@ -1209,10 +1209,12 @@ int machine__create_kernel_maps(struct machine *machine)*/ map_groups__fixup_end (&machine->kmaps); -if (machine__get_running_kernel_start (machine, &name, &addr)) { - }else if (maps__set_kallsyms_ref_reloc_sym (machine->vmlinux_maps, name, addr)) { -machine__destroy_kernel_maps (machine); -return -1 ; +if (!machine__get_running_kernel_start (machine, &name, &addr)) { +if (name && +maps__set_kallsyms_ref_reloc_sym (machine->vmlinux_maps, name, addr)) { +machine__destroy_kernel_maps (machine); +return -1 ; + } }return 0 ;