linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] ppdev: fix double-free of pp->pdev->name
@ 2016-10-30 22:19 Jann Horn
  2016-11-10  6:57 ` Greg Kroah-Hartman
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Jann Horn @ 2016-10-30 22:19 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman, Sudip Mukherjee
  Cc: linux-kernel, linux-parport, Andy Lutomirski

free_pardevice() is called by parport_unregister_device() and already frees
pp->pdev->name, don't try to do it again.

This bug causes kernel crashes.

I found and verified this with KASAN and some added pr_emerg()s:

[   60.316568] pp_release: pp->pdev->name == ffff88039cb264c0
[   60.316692] free_pardevice: freeing par_dev->name at ffff88039cb264c0
[   60.316706] pp_release: kfree(ffff88039cb264c0)
[   60.316714] ==========================================================
[   60.316722] BUG: Double free or freeing an invalid pointer
[   60.316731] Unexpected shadow byte: 0xFB
[   60.316801] Object at ffff88039cb264c0, in cache kmalloc-32 size: 32
[   60.316813] Allocated:
[   60.316824] PID = 1695
[   60.316869] Freed:
[   60.316880] PID = 1695
[   60.316935] ==========================================================

Signed-off-by: Jann Horn <jann@thejh.net>
---
 drivers/char/ppdev.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index d23368874710..6af1ce04b3da 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -748,10 +748,7 @@ static int pp_release(struct inode *inode, struct file *file)
 	}
 
 	if (pp->pdev) {
-		const char *name = pp->pdev->name;
-
 		parport_unregister_device(pp->pdev);
-		kfree(name);
 		pp->pdev = NULL;
 		pr_debug(CHRDEV "%x: unregistered pardevice\n", minor);
 	}
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] ppdev: fix double-free of pp->pdev->name
  2016-10-30 22:19 [PATCH v2] ppdev: fix double-free of pp->pdev->name Jann Horn
@ 2016-11-10  6:57 ` Greg Kroah-Hartman
  2016-11-10 12:40 ` Sudip Mukherjee
  2016-11-10 13:18 ` Arnd Bergmann
  2 siblings, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2016-11-10  6:57 UTC (permalink / raw)
  To: Jann Horn
  Cc: Arnd Bergmann, Sudip Mukherjee, linux-kernel, linux-parport,
	Andy Lutomirski

On Sun, Oct 30, 2016 at 11:19:24PM +0100, Jann Horn wrote:
> free_pardevice() is called by parport_unregister_device() and already frees
> pp->pdev->name, don't try to do it again.
> 
> This bug causes kernel crashes.
> 
> I found and verified this with KASAN and some added pr_emerg()s:
> 
> [   60.316568] pp_release: pp->pdev->name == ffff88039cb264c0
> [   60.316692] free_pardevice: freeing par_dev->name at ffff88039cb264c0
> [   60.316706] pp_release: kfree(ffff88039cb264c0)
> [   60.316714] ==========================================================
> [   60.316722] BUG: Double free or freeing an invalid pointer
> [   60.316731] Unexpected shadow byte: 0xFB
> [   60.316801] Object at ffff88039cb264c0, in cache kmalloc-32 size: 32
> [   60.316813] Allocated:
> [   60.316824] PID = 1695
> [   60.316869] Freed:
> [   60.316880] PID = 1695
> [   60.316935] ==========================================================
> 
> Signed-off-by: Jann Horn <jann@thejh.net>
> ---
>  drivers/char/ppdev.c | 3 ---
>  1 file changed, 3 deletions(-)

Sudip, I need an ack here before I can take this...

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] ppdev: fix double-free of pp->pdev->name
  2016-10-30 22:19 [PATCH v2] ppdev: fix double-free of pp->pdev->name Jann Horn
  2016-11-10  6:57 ` Greg Kroah-Hartman
@ 2016-11-10 12:40 ` Sudip Mukherjee
  2016-11-10 13:18 ` Arnd Bergmann
  2 siblings, 0 replies; 5+ messages in thread
From: Sudip Mukherjee @ 2016-11-10 12:40 UTC (permalink / raw)
  To: Jann Horn
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, linux-parport,
	Andy Lutomirski

On Sun, Oct 30, 2016 at 11:19:24PM +0100, Jann Horn wrote:
> free_pardevice() is called by parport_unregister_device() and already frees
> pp->pdev->name, don't try to do it again.
> 
> This bug causes kernel crashes.
> 
> I found and verified this with KASAN and some added pr_emerg()s:
> 
> [   60.316568] pp_release: pp->pdev->name == ffff88039cb264c0
> [   60.316692] free_pardevice: freeing par_dev->name at ffff88039cb264c0
> [   60.316706] pp_release: kfree(ffff88039cb264c0)
> [   60.316714] ==========================================================
> [   60.316722] BUG: Double free or freeing an invalid pointer
> [   60.316731] Unexpected shadow byte: 0xFB
> [   60.316801] Object at ffff88039cb264c0, in cache kmalloc-32 size: 32
> [   60.316813] Allocated:
> [   60.316824] PID = 1695
> [   60.316869] Freed:
> [   60.316880] PID = 1695
> [   60.316935] ==========================================================
> 
> Signed-off-by: Jann Horn <jann@thejh.net>
Acked-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] ppdev: fix double-free of pp->pdev->name
  2016-10-30 22:19 [PATCH v2] ppdev: fix double-free of pp->pdev->name Jann Horn
  2016-11-10  6:57 ` Greg Kroah-Hartman
  2016-11-10 12:40 ` Sudip Mukherjee
@ 2016-11-10 13:18 ` Arnd Bergmann
  2016-11-10 13:50   ` Sudip Mukherjee
  2 siblings, 1 reply; 5+ messages in thread
From: Arnd Bergmann @ 2016-11-10 13:18 UTC (permalink / raw)
  To: Jann Horn
  Cc: Greg Kroah-Hartman, Sudip Mukherjee, linux-kernel, linux-parport,
	Andy Lutomirski

On Sunday, October 30, 2016 11:19:24 PM CET Jann Horn wrote:
> diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
> index d23368874710..6af1ce04b3da 100644
> --- a/drivers/char/ppdev.c
> +++ b/drivers/char/ppdev.c
> @@ -748,10 +748,7 @@ static int pp_release(struct inode *inode, struct file *file)
>         }
>  
>         if (pp->pdev) {
> -               const char *name = pp->pdev->name;
> -
>                 parport_unregister_device(pp->pdev);
> -               kfree(name);
>                 pp->pdev = NULL;
>                 pr_debug(CHRDEV "%x: unregistered pardevice\n", minor);
>         }
> 

I took a closer look at this and found that we also leak the name
that is passed in register_device() in the same file:

        name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor);
...
        pdev = parport_register_dev_model(port, name, &ppdev_cb, minor);

parport_register_dev_model() copies the name using kstrdup() and
we should really free it after parport_register_dev_model().

It's not a huge problem, just leaking a few bytes of memory, but
the extra kfree() probably came from this confusion.

	Arnd

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] ppdev: fix double-free of pp->pdev->name
  2016-11-10 13:18 ` Arnd Bergmann
@ 2016-11-10 13:50   ` Sudip Mukherjee
  0 siblings, 0 replies; 5+ messages in thread
From: Sudip Mukherjee @ 2016-11-10 13:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Jann Horn, Greg Kroah-Hartman, linux-kernel, linux-parport,
	Andy Lutomirski

On Thu, Nov 10, 2016 at 02:18:12PM +0100, Arnd Bergmann wrote:
> On Sunday, October 30, 2016 11:19:24 PM CET Jann Horn wrote:
> > diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
> > index d23368874710..6af1ce04b3da 100644
> > --- a/drivers/char/ppdev.c
> > +++ b/drivers/char/ppdev.c
> > @@ -748,10 +748,7 @@ static int pp_release(struct inode *inode, struct file *file)
> >         }
> >  
> >         if (pp->pdev) {
> > -               const char *name = pp->pdev->name;
> > -
> >                 parport_unregister_device(pp->pdev);
> > -               kfree(name);
> >                 pp->pdev = NULL;
> >                 pr_debug(CHRDEV "%x: unregistered pardevice\n", minor);
> >         }
> > 
> 
> I took a closer look at this and found that we also leak the name
> that is passed in register_device() in the same file:
> 
>         name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor);
> ...
>         pdev = parport_register_dev_model(port, name, &ppdev_cb, minor);
> 
> parport_register_dev_model() copies the name using kstrdup() and
> we should really free it after parport_register_dev_model().

yes. I missed that while converting the driver to use device model.
Thanks. I will send a patch to fix this tonight.

> 
> It's not a huge problem, just leaking a few bytes of memory, but
> the extra kfree() probably came from this confusion.

No, it was the old code which was not in the device-model. The old code
uses parport_register_device() which just uses the same string that is
passed to it and so it was freed while releasing the device.

Regards
Sudip

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-11-10 13:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-30 22:19 [PATCH v2] ppdev: fix double-free of pp->pdev->name Jann Horn
2016-11-10  6:57 ` Greg Kroah-Hartman
2016-11-10 12:40 ` Sudip Mukherjee
2016-11-10 13:18 ` Arnd Bergmann
2016-11-10 13:50   ` Sudip Mukherjee

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).