Skip to contentSkip to conversation

uprobes: __create_xol_area() must nullify xol_mapping.fault

PATCH In review Oleg Nesterov 3 participants 5 messages Feb 27, 2016 – Feb 29, 2016

Subsystems (2)
lore
Share & tools
lore

Oleg Nesterov

author maintainer
#0 lore raw

PATCH 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
index 0167679..5f6ce93 100644
@@ -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
#1 lore raw
uprobes: __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
index 0167679..5f6ce93 100644
@@ -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])
maintainer
#2 lore raw
In reply to Oleg Nesterov
Quoted 23 lines · Oleg Nesterov

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 +0 -0
index 0167679..5f6ce93 100644

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 -0
 	area->pages[0] = alloc_page(GFP_HIGHUSER);
 	if (!area->pages[0])
author maintainer
#3 lore raw
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).

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.

maintainer
#4 lore raw
Quoted 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_mapping should go away, but we need a simple preparation in mm/mmap.c.

Yeah, no real strong feelings. Esp. if you're working on getting it killed.