aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2008-01-24 01:00:45 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-24 11:01:09 -0500
commitfabe874a48de45b137f99b4ed3641e0413f465ce (patch)
tree815204d845875bd14f5623766b2ec5bc6f1fe00c /kernel/lockdep.c
parent4784b11c4f49eb88f2dd74df6afc5170f193cedc (diff)
lockdep: fix kernel crash on module unload
Michael Wu noticed in his lkml post at http://marc.info/?l=linux-kernel&m=119396182726091&w=2 that certain wireless drivers ended up having their name in module memory, which would then crash the kernel on module unload. The patch he proposed was a bit clumsy in that it increased the size of a lockdep entry significantly; the patch below tries another approach, it checks, on module teardown, if the name of a class is in module space and then zaps the class. This is very similar to what we already do with keys that are in module space. Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 4335f12a27c..e2c07ece367 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -2932,7 +2932,7 @@ static void zap_class(struct lock_class *class)
2932 2932
2933} 2933}
2934 2934
2935static inline int within(void *addr, void *start, unsigned long size) 2935static inline int within(const void *addr, void *start, unsigned long size)
2936{ 2936{
2937 return addr >= start && addr < start + size; 2937 return addr >= start && addr < start + size;
2938} 2938}
@@ -2955,9 +2955,12 @@ void lockdep_free_key_range(void *start, unsigned long size)
2955 head = classhash_table + i; 2955 head = classhash_table + i;
2956 if (list_empty(head)) 2956 if (list_empty(head))
2957 continue; 2957 continue;
2958 list_for_each_entry_safe(class, next, head, hash_entry) 2958 list_for_each_entry_safe(class, next, head, hash_entry) {
2959 if (within(class->key, start, size)) 2959 if (within(class->key, start, size))
2960 zap_class(class); 2960 zap_class(class);
2961 else if (within(class->name, start, size))
2962 zap_class(class);
2963 }
2961 } 2964 }
2962 2965
2963 if (locked) 2966 if (locked)