Re: should failed calls to device_register() always call put_device()?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, May 28, 2011 at 06:00:10PM +0200, Belisko Marek wrote:
> Hi Robert,
> 
> On Sat, May 28, 2011 at 5:15 PM, Robert P. J. Day <rpjday@xxxxxxxxxxxxxx> wrote:
> >
> >  from drivers/base/core.c, we have the fairly unambiguous advice:
> >
> > * NOTE: _Never_ directly free @dev after calling this function, even
> > * if it returned an error! Always use put_device() to give up the
> > * reference initialized in this function instead.
> > */
> > int device_register(struct device *dev)
> > {
> >        device_initialize(dev);
> >        return device_add(dev);
> > }
> >
> >  and yet, there appears to be driver code that does exactly that,
> > such as this snippet from drivers/w1/w1_int.c (line 86):
> >
> >        ... snip ...
> >        err = device_register(&dev->dev);
> >        if (err) {
> >                printk(KERN_ERR "Failed to register master device. err=%d\n", err);
> >                memset(dev, 0, sizeof(struct w1_master));
> >                kfree(dev);
> >                dev = NULL;
> >        }
> Free is for allocated dev not for struct device so it is OK. IMO thi
> snippet should look like:
> err = device_register(&dev->dev);
> if (err) {
>     printk(KERN_ERR "Failed to register master device. err=%d\n", err);
>     put_device(&dev->dev);

Yes, that is correct.

>     memset(dev, 0, sizeof(struct w1_master));
>     kfree(dev);
>     dev = NULL;

Nope, you just accessed memory that was already freed twice, so you
could have oopsed any one of those times.

After the last put_device() happens, you CAN NOT touch the device again,
as it could be gone (might, might not, you don't really know, all you
know is you said you were done with it so you can't access it again.)

Hope this helps,

greg k-h

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux