From akpm@linux-foundation.org Wed Mar 12 14:42:35 2008 From: Ben Dooks Date: Tue, 04 Mar 2008 15:09:06 -0800 Subject: sysdev: detect multiple driver registrations To: greg@kroah.com Cc: akpm@linux-foundation.org, ben@fluff.org, kay.sievers@vrfy.org Message-ID: <200803042309.m24N96HF001980@imap1.linux-foundation.org> From: Ben Dooks I've just found how easy it is to accidentally register a sysdev_driver for two different classes. When this happens, bad things happen as the sysdev_driver structure keeps has the list entry for the driver registration. The following patch makes a WARN_ON() if this happens, although I think BUG_ON or returning -EAGAIN could also be valid responses to this. Signed-off-by: Ben Dooks Cc: Kay Sievers Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/base/sys.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -167,6 +167,22 @@ int sysdev_driver_register(struct sysdev { int err = 0; + if (!cls) { + printk(KERN_WARNING "sysdev: invalid class passed to " + "sysdev_driver_register!\n"); + WARN_ON(1); + return -EINVAL; + } + + /* Check whether this driver has already been added to a class. */ + if ((drv->entry.next != drv->entry.prev) || + (drv->entry.next != NULL)) { + printk(KERN_WARNING "sysdev: class %s: driver (%p) has already" + " been registered to a class, something is wrong, but " + "will forge on!\n", cls->name, drv); + WARN_ON(1); + } + mutex_lock(&sysdev_drivers_lock); if (cls && kset_get(&cls->kset)) { list_add_tail(&drv->entry, &cls->drivers);