فهرست منبع

tty: fix data race in tty_buffer_flush

tty_buffer_flush frees not acquired buffers.
As the result, for example, read of b->size in tty_buffer_free
can return garbage value which will lead to a huge buffer
hanging in the freelist. This is just the benignest
manifestation of freeing of a not acquired object.
If the object is passed to kfree, heap can be corrupted.

Acquire visibility over the buffer before freeing it.

The data race was found with KernelThreadSanitizer (KTSAN).

Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Dmitry Vyukov 10 سال پیش
والد
کامیت
9e6b7cd7e7
1فایلهای تغییر یافته به همراه4 افزوده شده و 1 حذف شده
  1. 4 1
      drivers/tty/tty_buffer.c

+ 4 - 1
drivers/tty/tty_buffer.c

@@ -242,7 +242,10 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
 	atomic_inc(&buf->priority);
 
 	mutex_lock(&buf->lock);
-	while ((next = buf->head->next) != NULL) {
+	/* paired w/ release in __tty_buffer_request_room; ensures there are
+	 * no pending memory accesses to the freed buffer
+	 */
+	while ((next = smp_load_acquire(&buf->head->next)) != NULL) {
 		tty_buffer_free(port, buf->head);
 		buf->head = next;
 	}