[IRDA]: Fix rfcomm use-after-free
authorMarcel Holtmann <marcel@holtmann.org>
Thu, 26 Jul 2007 07:12:25 +0000 (00:12 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Tue, 31 Jul 2007 09:28:05 +0000 (02:28 -0700)
Adrian Bunk wrote:
> Commit 8de0a15483b357d0f0b821330ec84d1660cadc4e added the following
> use-after-free in net/bluetooth/rfcomm/tty.c:
>
> <--  snip  -->
>
> ...
> static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
> {
> ...
>         if (IS_ERR(dev->tty_dev)) {
>                 list_del(&dev->list);
>                 kfree(dev);
>                 return PTR_ERR(dev->tty_dev);
>         }
> ...
>
> <--  snip  -->
>
> Spotted by the Coverity checker.

really good catch. I fully overlooked that one. The attached patch
should fix it.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/bluetooth/rfcomm/tty.c

index 23ba61a..22a8320 100644 (file)
@@ -267,7 +267,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 out:
        write_unlock_bh(&rfcomm_dev_lock);
 
 out:
        write_unlock_bh(&rfcomm_dev_lock);
 
-       if (err) {
+       if (err < 0) {
                kfree(dev);
                return err;
        }
                kfree(dev);
                return err;
        }
@@ -275,9 +275,10 @@ out:
        dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
 
        if (IS_ERR(dev->tty_dev)) {
        dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
 
        if (IS_ERR(dev->tty_dev)) {
+               err = PTR_ERR(dev->tty_dev);
                list_del(&dev->list);
                kfree(dev);
                list_del(&dev->list);
                kfree(dev);
-               return PTR_ERR(dev->tty_dev);
+               return err;
        }
 
        return dev->id;
        }
 
        return dev->id;