On Mon, 2013-03-04 at 23:19 +0400, Ilya Zykov wrote: > On 03.12.2012 13:54, Ilya Zykov wrote: > > The root of problem is carelessly zeroing pointer(in function __tty_buffer_flush()), > > when another thread can use it. It can be cause of "NULL pointer dereference". > > Main idea of the patch, this is never release last (struct tty_buffer) in the active buffer. > > Only flush data for ldisc(tty->buf.head->read = tty->buf.head->commit). > > At that moment driver can collect(write) data in buffer without conflict. > > It is repeat behavior of flush_to_ldisc(), only without feeding data to ldisc. > > Test program and bug report you can see: > > https://lkml.org/lkml/2012/11/29/368 > > > > Cc: stable@xxxxxxxxxxxxxxx > > Signed-off-by: Ilya Zykov <ilya@xxxxxxx> > > --- > > diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c > > index 6c9b7cd..4f02f9c 100644 > > --- a/drivers/tty/tty_buffer.c > > +++ b/drivers/tty/tty_buffer.c > > @@ -114,11 +114,14 @@ static void __tty_buffer_flush(struct tty_struct *tty) > > { > > struct tty_buffer *thead; > > > > - while ((thead = tty->buf.head) != NULL) { > > - tty->buf.head = thead->next; > > - tty_buffer_free(tty, thead); > > + if (tty->buf.head == NULL) > > + return; > > + while ((thead = tty->buf.head->next) != NULL) { > > + tty_buffer_free(tty, tty->buf.head); > > + tty->buf.head = thead; > > } > > - tty->buf.tail = NULL; > > + WARN_ON(tty->buf.head != tty->buf.tail); > > + tty->buf.head->read = tty->buf.head->commit; > > } > > > > /** > > > > You can include this patch, in 3.2 series , for improve stability, > it would be merged in upstream 3.9-rc1. Added to the queue, thanks. Ben. -- Ben Hutchings Usenet is essentially a HUGE group of people passing notes in class. - Rachel Kadel, `A Quick Guide to Newsgroup Etiquette'
Attachment:
signature.asc
Description: This is a digitally signed message part