Commit 1b2439dbb703ae8d95a9ce7ece6b7800b80f41f0

Authored by Arjan van de Ven
Committed by Ingo Molnar
1 parent b09c3e3f17

debug: add notifier chain debugging

during some development we suspected a case where we left something
in a notifier chain that was from a module that was unloaded already...
and that sort of thing is rather hard to track down.

This patch adds a very simple sanity check (which isn't all that
expensive) to make sure the notifier we're about to call is
actually from either the kernel itself of from a still-loaded
module, avoiding a hard-to-chase-down crash.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 2 changed files with 26 additions and 0 deletions Side-by-side Diff

... ... @@ -21,6 +21,10 @@
21 21 static int notifier_chain_register(struct notifier_block **nl,
22 22 struct notifier_block *n)
23 23 {
  24 + if (!kernel_text_address((unsigned long)n->notifier_call)) {
  25 + WARN(1, "Invalid notifier registered!");
  26 + return 0;
  27 + }
24 28 while ((*nl) != NULL) {
25 29 if (n->priority > (*nl)->priority)
26 30 break;
... ... @@ -34,6 +38,10 @@
34 38 static int notifier_chain_cond_register(struct notifier_block **nl,
35 39 struct notifier_block *n)
36 40 {
  41 + if (!kernel_text_address((unsigned long)n->notifier_call)) {
  42 + WARN(1, "Invalid notifier registered!");
  43 + return 0;
  44 + }
37 45 while ((*nl) != NULL) {
38 46 if ((*nl) == n)
39 47 return 0;
... ... @@ -82,6 +90,14 @@
82 90  
83 91 while (nb && nr_to_call) {
84 92 next_nb = rcu_dereference(nb->next);
  93 +
  94 +#ifdef CONFIG_DEBUG_NOTIFIERS
  95 + if (!kernel_text_address((unsigned long)nb->notifier_call)) {
  96 + WARN(1, "Invalid notifier called!");
  97 + nb = next_nb;
  98 + continue;
  99 + }
  100 +#endif
85 101 ret = nb->notifier_call(nb, val, v);
86 102  
87 103 if (nr_calls)
... ... @@ -536,6 +536,16 @@
536 536  
537 537 If unsure, say N.
538 538  
  539 +config DEBUG_NOTIFIERS
  540 + bool "Debug notifier call chains"
  541 + depends on DEBUG_KERNEL
  542 + help
  543 + Enable this to turn on sanity checking for notifier call chains.
  544 + This is most useful for kernel developers to make sure that
  545 + modules properly unregister themselves from notifier chains.
  546 + This is a relatively cheap check but if you care about maximum
  547 + performance, say N.
  548 +
539 549 config FRAME_POINTER
540 550 bool "Compile the kernel with frame pointers"
541 551 depends on DEBUG_KERNEL && \