Re: [PATCH 0/2] printk: replace ringbuffer

From: John Ogness
Date: Wed Feb 05 2020 - 10:48:47 EST


On 2020-02-05, Sergey Senozhatsky <sergey.senozhatsky@xxxxxxxxx> wrote:
> 3BUG: KASAN: wild-memory-access in copy_data+0x129/0x220>
> 3Write of size 4 at addr 5a5a5a5a5a5a5a5a by task cat/474>

The problem was due to an uninitialized pointer.

Very recently the ringbuffer API was expanded so that it could
optionally count lines in a record. This made it possible for me to
implement record_print_text_inline(), which can do all the kmsg_dump
multi-line madness without requiring a temporary buffer. Rather than
passing an extra argument around for the optional line count, I added
the text_line_count pointer to the printk_record struct. And since line
counting is rarely needed, it is only performed if text_line_count is
non-NULL.

I oversaw that devkmsg_open() setup a printk_record and so I did not see
to add the extra NULL initialization of text_line_count. There should be
be an initializer function/macro to avoid this danger.

John Ogness

The quick fixup:

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index d0d24ee1d1f4..5ad67ff60cd9 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -883,6 +883,7 @@ static int devkmsg_open(struct inode *inode, struct file *file)
user->record.text_buf_size = sizeof(user->text_buf);
user->record.dict_buf = &user->dict_buf[0];
user->record.dict_buf_size = sizeof(user->dict_buf);
+ user->record.text_line_count = NULL;

logbuf_lock_irq();
user->seq = prb_first_seq(prb);