uprobes: __create_xol_area() must nullify xol_mapping.fault
Subsystems (2)
Oleg Nesterov
maintainerPATCH 1/1 uprobes: __create_xol_area() must nullify xol_mapping.fault
As Jiri pointed out, the recent commit f872f5400cc0 "mm: Add a vm_special_mapping.fault() method" breaks uprobes. __create_xol_area() doesn't initialize the new ->fault() method and this obviously leads to kernel crash when the application tries to execute the probed insn after bp hit.
We probably want to add uprobes_special_mapping_fault(), this allows to turn xol_area->xol_mapping into a single instance of vm_special_mapping. But we need a simple fix, so lets change __create_xol() to nullify the new member as Jiri suggests.
--- kernel/events/uprobes.c | 1 + 1 file changed, 1 insertion(+)
kernel/events/uprobes.c +1 -0
@@ -1178,6 +1178,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) goto free_area; area->xol_mapping.name ="[uprobes]" ; + area->xol_mapping.fault =NULL ; area->xol_mapping.pages = area->pages; area->pages[0 ] =alloc_page (GFP_HIGHUSER );if (!area->pages[0 ])
Signature · 1 line
2.5.0
tip-bot for Oleg Nesterov
merge botuprobes: __create_xol_area() must nullify xol_mapping.fault
Commit-ID: 869ae76147ffdf21ad24f0e599303cd58a2bb39f Gitweb: http://git.kernel.org/tip/869ae76147ffdf21ad24f0e599303cd58a2bb39f Author: Oleg Nesterov <[email protected]> AuthorDate: Sat, 27 Feb 2016 23:11:28 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Mon, 29 Feb 2016 08:47:51 +0100
uprobes: __create_xol_area() must nullify xol_mapping.fault
As Jiri pointed out, this recent commit:
f872f5400cc0 ("mm: Add a vm_special_mapping.fault() method")
breaks uprobes: __create_xol_area() doesn't initialize the new ->fault() method and this obviously leads to kernel crash when the application tries to execute the probed insn after bp hit.
We probably want to add uprobes_special_mapping_fault(), this allows to turn xol_area->xol_mapping into a single instance of vm_special_mapping. But we need a simple fix, so lets change __create_xol() to nullify the new member as Jiri suggests.
--- kernel/events/uprobes.c | 1 + 1 file changed, 1 insertion(+)
kernel/events/uprobes.c +1 -0
@@ -1178,6 +1178,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) goto free_area; area->xol_mapping.name ="[uprobes]" ; + area->xol_mapping.fault =NULL ; area->xol_mapping.pages = area->pages; area->pages[0 ] =alloc_page (GFP_HIGHUSER );if (!area->pages[0 ])
Peter Zijlstra
maintainerQuoted 23 lines · Oleg Nesterov
As Jiri pointed out, the recent commit
f872f5400cc0"mm: Add avm_special_mapping.fault()method" breaks uprobes.__create_xol_area()doesn't initialize the new ->fault() method and this obviously leads to kernel crash when the application tries to execute the probed insn after bp hit.We probably want to add
uprobes_special_mapping_fault(), this allows to turnxol_area->xol_mappinginto a single instance ofvm_special_mapping. But we need a simple fix, so lets change__create_xol()to nullify the new member as Jiri suggests.Reported-by Jiri Olsa <[email protected]>Suggested-by Jiri Olsa <[email protected]>Signed-off-by Oleg Nesterov <[email protected]>--- kernel/events/uprobes.c | 1 + 1 file changed, 1 insertion(+)kernel/events/uprobes.c +0
-0
kernel/events/uprobes.c static struct xol_area *__create_xol_area(unsigned long vaddr) · line 1182
Quoted 5 lines
kernel/events/uprobes.c +1
-0@@ -1178,6 +1178,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) goto free_area; area->xol_mapping.name ="[uprobes]" ; + area->xol_mapping.fault =NULL ; area->xol_mapping.pages = area->pages;
Would not something like:
area->xol_mapping = (struct vm_special_mapping){
.name = "[uprobes]",
.pages = area->pages,
};Be a more robust approach? That way, if someone adds more fields, they at least get initialized (to 0).
Quoted 2 lines
kernel/events/uprobes.c +0
-0area->pages[0 ] =alloc_page (GFP_HIGHUSER );if (!area->pages[0 ])
Oleg Nesterov
maintainerQuoted 13 lines · Peter Zijlstra
kernel/events/uprobes.c static struct xol_area *__create_xol_area(unsigned long vaddr) · line 1182
Quoted 8 lines · Oleg Nesterov
kernel/events/uprobes.c +1
-0@@ -1178,6 +1178,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) goto free_area; area->xol_mapping.name ="[uprobes]" ; + area->xol_mapping.fault =NULL ; area->xol_mapping.pages = area->pages;Would not something like:
Quoted 7 lines
area->xol_mapping = (struct vm_special_mapping){ .name = "[uprobes]", .pages = area->pages, };Be a more robust approach? That way, if someone adds more fields, they at least get initialized (to 0).
OK, agreed...
Do you want me to send v2? Or incremental patch because this one is already in -tip tree.
Or do nothing unless you feel strongly about it. area->xol_mapping should go away, but we need a simple preparation in mm/mmap.c.
Oleg.
Peter Zijlstra
maintainerQuoted 22 lines · Oleg Nesterov
Quoted 13 lines · Peter Zijlstra
kernel/events/uprobes.c static struct xol_area *__create_xol_area(unsigned long vaddr) · line 1182
Quoted 8 lines · Oleg Nesterov
kernel/events/uprobes.c +1
-0@@ -1178,6 +1178,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) goto free_area; area->xol_mapping.name ="[uprobes]" ; + area->xol_mapping.fault =NULL ; area->xol_mapping.pages = area->pages;Would not something like:
Quoted 7 lines
area->xol_mapping = (struct vm_special_mapping){ .name = "[uprobes]", .pages = area->pages, };Be a more robust approach? That way, if someone adds more fields, they at least get initialized (to 0).
Quoted 7 lines
OK, agreed...
Do you want me to send v2? Or incremental patch because this one is already in -tip tree.
Or do nothing unless you feel strongly about it.
area->xol_mappingshould go away, but we need a simple preparation inmm/mmap.c.
Yeah, no real strong feelings. Esp. if you're working on getting it killed.