Messages in this thread Patch in this message | | | Date | Wed, 27 Apr 2005 00:09:25 +0200 (CEST) | From | Jesper Juhl <> | Subject | Re: [PATCH] Don't oops when unregistering unknown kprobes |
| |
On Tue, 26 Apr 2005, Frederik Deweerdt wrote:
> Le 26/04/05 21:57 +0530, Prasanna S Panchamukhi écrivit: > > This is wrong. You should call get_kprobe() with spin_lock(). > > > Right, corrected patch attached. It also sets flags to zero. > Signed-off-by: Frederik Deweerdt <frederik.deweerdt@laposte.net>
> --- linux-2.6.12-rc3/kernel/kprobes.c 2005-04-26 16:35:22.000000000 +0200 > +++ linux-2.6.12-rc3-devel/kernel/kprobes.c 2005-04-26 23:18:47.000000000 +0200 > @@ -106,13 +106,22 @@ rm_kprobe: > > void unregister_kprobe(struct kprobe *p) > { > - unsigned long flags; > + unsigned long flags = 0; > + > + spin_lock_irqsave(&kprobe_lock, flags); ^^^ +one...
> + if (!get_kprobe(p)) { > + printk(KERN_WARNING "Warning: Attempt to unregister " > + "unknown kprobe (addr:0x%lx)\n", > + (unsigned long) p); > + goto out; > + } > arch_remove_kprobe(p); > spin_lock_irqsave(&kprobe_lock, flags); ^^^ +two...
> *p->addr = p->opcode; > hlist_del(&p->hlist); > flush_icache_range((unsigned long) p->addr, > (unsigned long) p->addr + sizeof(kprobe_opcode_t)); > +out: > spin_unlock_irqrestore(&kprobe_lock, flags); ^^^ -one...
> }
Seems to me this will end up calling spin_lock_irqsave() twice, but only spin_unlock_irqrestore once in the non-failing case... hmm..
Also, as Chris Wedgwood asked, why not simply return -EINVAL; instead of the printk()? Does the user really care that we tried to unregister a nonexisting kprobe? and if you really think someone would like to know then I'd personally say that KERN_DEBUG should be sufficient.
I'd suggest something like this :
Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
--- linux-2.6.12-rc2-mm3-orig/kernel/kprobes.c 2005-04-11 21:20:56.000000000 +0200 +++ linux-2.6.12-rc2-mm3/kernel/kprobes.c 2005-04-27 00:04:23.000000000 +0200 @@ -108,16 +108,24 @@ rm_kprobe: return ret; } -void unregister_kprobe(struct kprobe *p) +int unregister_kprobe(struct kprobe *p) { - unsigned long flags; - arch_remove_kprobe(p); + unsigned long flags = 0; + int ret = 0; + spin_lock_irqsave(&kprobe_lock, flags); + if (!get_kprobe(p)) { + ret = -EINVAL; + goto out; + } + arch_remove_kprobe(p); *p->addr = p->opcode; hlist_del(&p->hlist); flush_icache_range((unsigned long) p->addr, (unsigned long) p->addr + sizeof(kprobe_opcode_t)); +out: spin_unlock_irqrestore(&kprobe_lock, flags); + return ret; }
And if you really want that printk in there, then this should make you happy - but personally I don't see the big need : + if (!get_kprobe(p)) { + printk(KERN_DEBUG "Warning: Attempt to unregister " + "unknown kprobe (addr:0x%lx)\n", + (unsigned long) p); + ret = -EINVAL; + goto out; + }
Ohh and btw, would you mind posting patches inline? Having to save the patch, add quotes to it and then read it back into the reply mail to comment on it is a pain...
And don't trim the CC: list when replying to mails on LKML, please.
-- Jesper Juhl
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |