Thread (368 messages) 368 messages, 25 authors, 2015-02-16

Re: [PATCH v11 19/19] kasan: enable instrumentation of global variables

From: Rusty Russell <hidden>
Date: 2015-02-16 23:56:20
Also in: linux-kbuild, lkml

Andrey Ryabinin [off-list ref] writes:
On 02/16/2015 05:58 AM, Rusty Russell wrote:
quoted
Andrey Ryabinin [off-list ref] writes:
quoted
This feature let us to detect accesses out of bounds of
global variables. This will work as for globals in kernel
image, so for globals in modules. Currently this won't work
for symbols in user-specified sections (e.g. __init, __read_mostly, ...)
@@ -1807,6 +1808,7 @@ static void unset_module_init_ro_nx(struct module *mod) { }
 void __weak module_memfree(void *module_region)
 {
 	vfree(module_region);
+	kasan_module_free(module_region);
 }
This looks racy (memory reuse?).  Perhaps try other order?
You are right, it's racy. Concurrent kasan_module_alloc() could fail because
kasan_module_free() wasn't called/finished yet, so whole module_alloc() will fail
and module loading will fail.
However, I just find out that this race is not the worst problem here.
When vfree(addr) called in interrupt context, memory at addr will be reused for
storing 'struct llist_node':

void vfree(const void *addr)
{
...
	if (unlikely(in_interrupt())) {
		struct vfree_deferred *p = this_cpu_ptr(&vfree_deferred);
		if (llist_add((struct llist_node *)addr, &p->list))
			schedule_work(&p->wq);


In this case we have to free shadow *after* freeing 'module_region', because 'module_region'
is still used in llist_add() and in free_work() latter.
free_work() (in mm/vmalloc.c) processes list in LIFO order, so to free shadow after freeing
'module_region' kasan_module_free(module_region); should be called before vfree(module_region);

It will be racy still, but this is not so bad as potential crash that we have now.
Honestly, I have no idea how to fix this race nicely. Any suggestions?
I think you need to take over the rcu callback for the kasan case.

Perhaps we rename that __module_memfree(), and do:

void module_memfree(void *p)
{
#ifdef CONFIG_KASAN
        ...
#endif
        __module_memfree(p);        
}

Note: there are calls to module_memfree from other code (BPF and
kprobes).  I assume you looked at those too...

Cheers,
Rusty.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help