diff options
author | Erick Reyes <erickreyes@google.com> | 2018-08-15 17:55:48 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-08-17 20:54:55 +0200 |
commit | 84d2099e70072468af1f565853f8958d9e12e3fd (patch) | |
tree | 9e42d030e20698dcc74f925ef77f7c1e69508ae3 /sound/core | |
parent | 208255c7a3bfdb4e7a02d1aba8c4c68affd9027e (diff) | |
download | linux-stable-84d2099e70072468af1f565853f8958d9e12e3fd.tar.gz linux-stable-84d2099e70072468af1f565853f8958d9e12e3fd.tar.bz2 linux-stable-84d2099e70072468af1f565853f8958d9e12e3fd.zip |
ALSA: info: Check for integer overflow in snd_info_entry_write()
Commit 4adb7bcbcb69 ("ALSA: core: Use seq_file for text proc file
reads") heavily refactored ALSA procfs and fixed the overflow as
a side-effect, so this fix only applies to kernels < 4.2 and
there is no upstream equivalent
snd_info_entry_write() resizes the buffer with an unsigned long
size argument that gets truncated because resize_info_buffer()
takes the size parameter as an unsigned int. On 64-bit kernels,
this causes the following copy_to_user() to write out-of-bounds
if (pos + count) can't be represented by an unsigned int.
Signed-off-by: Siqi Lin <siqilin@google.com>
Signed-off-by: Erick Reyes <erickreyes@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/info.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/sound/core/info.c b/sound/core/info.c index 9f404e965ea2..08832c973a53 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -253,6 +253,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer struct snd_info_buffer *buf; ssize_t size = 0; loff_t pos; + unsigned long realloc_size; data = file->private_data; if (snd_BUG_ON(!data)) @@ -261,7 +262,8 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer pos = *offset; if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) return -EIO; - if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos) + realloc_size = (unsigned long) pos + (unsigned long) count; + if (realloc_size < (unsigned long) pos || realloc_size > UINT_MAX) return -EIO; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: |