Re: [PATCH V2] [tty] Fix possible race in n_tty_read()

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

 



On Thu, Aug 09, 2012 at 01:16:20PM +0200, Stanislaw Gruszka wrote:
> On Wed, Aug 08, 2012 at 04:27:25PM +0100, Alan Cox wrote:
> > On Wed, 08 Aug 2012 16:28:47 +0200
> > Stanislav Kozina <skozina@xxxxxxxxxx> wrote:
> > 
> > > Fix possible panic caused by unlocked access to tty->read_cnt in 
> > > while-loop condition in n_tty_read().
> > 
> > Should this also be removing the BUG_ON check you noted in the other
> > email was not valid now ?
> 
> You talk about 
> http://marc.info/?l=linux-serial&m=134318985920881&w=2
> 
> Is possible that we can call n_tty_read() after n_tty_close() ? How oterwise
> tty->read_buf could become NULL?
> 
> If I understand correctly Stanislav's patch solve below race condtion:
> 
> CPU0					CPU1
> n_tty_read:				reset_buffer_flags:
> 
> while (nr && tty->read_cnt) {
> 
>   					spin_lock_irqsave(&tty->read_lock, flags);
> 					tty->read_head = tty->read_tail = tty->read_cnt = 0;
>   					spin_lock_irqsave(&tty->read_lock, flags);
> 
>   spin_lock_irqsave(&tty->read_lock, flags);
>   
>   tty->read_cnt--;
> 
>   spin_lock_irqsave(&tty->read_lock, flags);
> 
>   /* Now tty->read_cnt is negative */
> 
> }
> 
> what itself could have varsious nasty consequences, i.e. ininite
> loop. Is also possible that negative tty->read_cnt would result in
> tty->read_buf == NULL ? If so, I'm not quite understand that.

I looked a bit more at this. Excluding memory corruption which could
zero tty struct, the only possibility to nullify tty->read_buf is
call to n_tty_close(). So NULL pointer dereference on n_tty_read,
in "while (nr && tty->read_cnt)" loop can only be caused by calling
n_tty_close(), while performing n_tty_read().

Stanislav patch solve that problem because we do not touch tty->read_buf
any longer once tty->read_cnt become 0, and because n_tty_close() clear
tty->read_cnt (by calling n_tty_flush_buffer() -> reset_buffer_flags()).

However looks like main problem persist, we should never do
n_tty_read() after/during n_tty_close() and before n_tty_open(). That
must be an issue in upper layer i.e. tty_io and tty_ldisc, which should
give guarantee about ->close(), ->read(), ->open() ordering. I'm going
to look at that more closely.

Stanislaw
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux