Enclosed is a potential race in drv_stat_unload. It seems suspicious:
- potentially a use-after-free (if put_drv deallocs)
- potentially a race where the global var drv->channels is used without
protection (or is this routine called with drivers_lock held?)
Dawson
/u2/engler/mc/oses/linux/linux-2.5.62/drivers/isdn/i4l/isdn_common.c:636:drv_stat_unload:ERROR:RACE:636:636:unprotected access to variable (*dev).channels,isdn_dev.channels,1[nvars=2] [vars=(*dev).channels,isdn_dev.channels,1:636 (*dev).channels,isdn_dev.channels,1:636 ][non_csect_reads=1] [non_csect_writes=1][modified=1] [locked_uses=1] [unlocked_uses=1] [n_writes=2] [n_reads=3] [n_root=2] [n_file_write=1] [n_file_read=1] [n_unlocked=1][has_locked=1] [depth=1] [path=/u2/engler/mc/oses/linux/linux-2.5.62/drivers/isdn/i4l/isdn_common.c:drv_stat_unload:634->end=/u2/engler/mc/oses/linux/linux-2.5.62/drivers/isdn/i4l/isdn_common.c:drv_stat_unload:636] [score=5] [z=-0.62] [rank=easy]
spin_lock_irqsave(&drivers_lock, flags);
drivers[drv->di] = NULL;
spin_unlock_irqrestore(&drivers_lock, flags);
put_drv(drv);
Error --->
dev->channels -= drv->channels;
isdn_info_update();
return 0;
On Sat, 22 Mar 2003, Dawson Engler wrote:
> /u2/engler/mc/oses/linux/linux-2.5.62/drivers/isdn/i4l/isdn_common.c:636:drv_stat_unload:ERROR:RACE:636:636:unprotected access to variable (*dev).channels,isdn_dev.channels,1[nvars=2] [vars=(*dev).channels,isdn_dev.channels,1:636 (*dev).channels,isdn_dev.channels,1:636 ][non_csect_reads=1] [non_csect_writes=1][modified=1] [locked_uses=1] [unlocked_uses=1] [n_writes=2] [n_reads=3] [n_root=2] [n_file_write=1] [n_file_read=1] [n_unlocked=1][has_locked=1] [depth=1] [path=/u2/engler/mc/oses/linux/linux-2.5.62/drivers/isdn/i4l/isdn_common.c:drv_stat_unload:634->end=/u2/engler/mc/oses/linux/linux-2.5.62/drivers/isdn/i4l/isdn_common.c:drv_stat_unload:636] [score=5] [z=-0.62] [rank=easy]
>
> spin_lock_irqsave(&drivers_lock, flags);
> drivers[drv->di] = NULL;
> spin_unlock_irqrestore(&drivers_lock, flags);
> put_drv(drv);
>
>
> Error --->
> dev->channels -= drv->channels;
>
Yes, that's a bug. I'll fix it.
Thanks,
--Kai