diff options
author | Pavel Shved <shved@ispras.ru> | 2011-06-17 06:25:11 +0000 |
---|---|---|
committer | David S. Miller <davem@conan.davemloft.net> | 2011-06-17 15:27:32 -0400 |
commit | 2f9381e98471837b631743270de988e78aad1f96 (patch) | |
tree | 8d87fe2573694a91f8ae46e5bb90d2096c1a45a4 /drivers/isdn | |
parent | d0fd64c1de437bdf91c32d4f84a53fa4b2150348 (diff) | |
download | linux-2f9381e98471837b631743270de988e78aad1f96.tar.gz linux-2f9381e98471837b631743270de988e78aad1f96.tar.bz2 linux-2f9381e98471837b631743270de988e78aad1f96.zip |
gigaset: call module_put before restart of if_open()
if_open() calls try_module_get(), and after an attempt to lock a mutex
the if_open() function may return -ERESTARTSYS without
putting the module. Then, when if_open() is executed again,
try_module_get() is called making the reference counter of THIS_MODULE
greater than one at successful exit from if_open(). The if_close()
function puts the module only once, and as a result it can't be
unloaded.
This patch adds module_put call before the return from if_open().
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Pavel Shved <shved@ispras.ru>
Signed-off-by: David S. Miller <davem@conan.davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/gigaset/interface.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 59de638225fe..e35058bcd7b9 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -156,8 +156,10 @@ static int if_open(struct tty_struct *tty, struct file *filp) if (!cs || !try_module_get(cs->driver->owner)) return -ENODEV; - if (mutex_lock_interruptible(&cs->mutex)) + if (mutex_lock_interruptible(&cs->mutex)) { + module_put(cs->driver->owner); return -ERESTARTSYS; + } tty->driver_data = cs; ++cs->open_count; |