Messages in this thread | ![/](/images/icornerl.gif) | | Date | Tue, 23 Apr 2024 21:46:35 +0700 | Subject | Re: [PATCH 5/5] drivers/s390/cio: ensure the copied buf is NULL terminated | From | Bui Quang Minh <> |
| |
On 4/23/24 13:50, Heiko Carstens wrote: > On Mon, Apr 22, 2024 at 11:41:40PM +0700, Bui Quang Minh wrote: >> Currently, we allocate a lbuf-sized kernel buffer and copy lbuf from >> userspace to that buffer. Later, we use scanf on this buffer but we don't >> ensure that the string is terminated inside the buffer, this can lead to >> OOB read when using scanf. Fix this issue by allocating 1 more byte to at >> the end of buffer and write NULL terminator to the end of buffer after >> userspace copying. >> >> Fixes: a4f17cc72671 ("s390/cio: add CRW inject functionality") >> Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com> >> --- >> drivers/s390/cio/cio_inject.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/s390/cio/cio_inject.c b/drivers/s390/cio/cio_inject.c >> index 8613fa937237..9b69fbf49f60 100644 >> --- a/drivers/s390/cio/cio_inject.c >> +++ b/drivers/s390/cio/cio_inject.c >> @@ -95,10 +95,11 @@ static ssize_t crw_inject_write(struct file *file, const char __user *buf, >> return -EINVAL; >> } >> >> - buffer = vmemdup_user(buf, lbuf); >> + buffer = vmemdup_user(buf, lbuf + 1); >> if (IS_ERR(buffer)) >> return -ENOMEM; >> >> + buffer[lbuf] = '\0'; > > This would read one byte too much from user space, and could potentially > fault. > > Why isn't this simply memdup_user_nul() like all others, which would do the > right thing?
Thanks for your review. It's my mistake, I blindly follow the pattern in rvu_debugfs
static ssize_t rvu_dbg_qsize_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos, int blktype) { cmd_buf = memdup_user(buffer, count + 1); if (IS_ERR(cmd_buf)) return -ENOMEM;
cmd_buf[count] = '\0'; }
I will send a patch to fix this too.
For this case, as the original code uses vmemdup_user, which internally uses kvmalloc not kmalloc, so I try to keep the original behavior. And vmemdup_user does not have the counterpart vmemdup_user_nul. I can kvmalloc(lbuf + 1), then copy_to_user(lbuf) and set buffer[lbuf] = '\0' or do you think I should create vmemdup_user_nul?
Thanks, Quang Minh.
| ![\](/images/icornerr.gif) |