From d513484f62318f4610c68d047388fad7d8a31e74 Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Wed, 12 Jul 2017 13:49:53 +0200 Subject: [PATCH] add CVE fixes CVE-2014-9900: net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() CVE-2017-7346: drm/vmwgfx: limit the number of mip levels in vmw_gb_surface_define_ioctl() CVE-2017-9605: drm/vmwgfx: Make sure backup_handle is always valid CVE-2017-1000380: * ALSA: timer: Fix race between read and ioctl * ALSA: timer: Fix missing queue indices reset at SNDRV_TIMER_IOCTL_SELECT Signed-off-by: Thomas Lamprecht --- ...structure-ethtool_wolinfo-in-ethtool.patch | 47 +++++++++++ ...issing-queue-indices-reset-at-SNDRV_.patch | 66 +++++++++++++++ ...imer-Fix-race-between-read-and-ioctl.patch | 83 +++++++++++++++++++ ...-the-number-of-mip-levels-in-vmw_gb_.patch | 46 ++++++++++ ...e-sure-backup_handle-is-always-valid.patch | 68 +++++++++++++++ Makefile | 5 ++ 6 files changed, 315 insertions(+) create mode 100644 CVE-2014-9900-net-Zeroing-the-structure-ethtool_wolinfo-in-ethtool.patch create mode 100644 CVE-2017-1000380-ALSA-timer-Fix-missing-queue-indices-reset-at-SNDRV_.patch create mode 100644 CVE-2017-1000380-ALSA-timer-Fix-race-between-read-and-ioctl.patch create mode 100644 CVE-2017-7346-drm-vmwgfx-limit-the-number-of-mip-levels-in-vmw_gb_.patch create mode 100644 CVE-2017-9605-drm-vmwgfx-Make-sure-backup_handle-is-always-valid.patch diff --git a/CVE-2014-9900-net-Zeroing-the-structure-ethtool_wolinfo-in-ethtool.patch b/CVE-2014-9900-net-Zeroing-the-structure-ethtool_wolinfo-in-ethtool.patch new file mode 100644 index 0000000..146ef95 --- /dev/null +++ b/CVE-2014-9900-net-Zeroing-the-structure-ethtool_wolinfo-in-ethtool.patch @@ -0,0 +1,47 @@ +From 38e360ea72f11241adede7ea2b22d8d536fe490b Mon Sep 17 00:00:00 2001 +From: Avijit Kanti Das +Date: Thu, 8 Jun 2017 15:41:00 +0200 +Subject: [PATCH 5/5] net: Zeroing the structure ethtool_wolinfo in + ethtool_get_wol() + +CVE-2014-9900 + +memset() the structure ethtool_wolinfo that has padded bytes +but the padded bytes have not been zeroed out. + +Change-Id: If3fd2d872a1b1ab9521d937b86a29fc468a8bbfe +Signed-off-by: Avijit Kanti Das +(cherry-picked from commit 63c317dbee97983004dffdd9f742a20d17150071 + https://source.codeaurora.org/quic/la/kernel/msm-3.10) +Signed-off-by: Brad Figg +Acked-by: Seth Forshee +Acked-by: Colin King +Signed-off-by: Stefan Bader + +Signed-off-by: Thomas Lamprecht +--- + net/core/ethtool.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/core/ethtool.c b/net/core/ethtool.c +index d92de0a1f0a4..c06c6acf78c5 100644 +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -1449,11 +1449,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr) + + static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) + { +- struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; ++ struct ethtool_wolinfo wol; + + if (!dev->ethtool_ops->get_wol) + return -EOPNOTSUPP; + ++ memset(&wol, 0, sizeof(struct ethtool_wolinfo)); ++ wol.cmd = ETHTOOL_GWOL; + dev->ethtool_ops->get_wol(dev, &wol); + + if (copy_to_user(useraddr, &wol, sizeof(wol))) +-- +2.11.0 + diff --git a/CVE-2017-1000380-ALSA-timer-Fix-missing-queue-indices-reset-at-SNDRV_.patch b/CVE-2017-1000380-ALSA-timer-Fix-missing-queue-indices-reset-at-SNDRV_.patch new file mode 100644 index 0000000..8753fc7 --- /dev/null +++ b/CVE-2017-1000380-ALSA-timer-Fix-missing-queue-indices-reset-at-SNDRV_.patch @@ -0,0 +1,66 @@ +From 993c7c14bbc4bf51025bb5c83c1c130417e0e823 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 21 Jun 2017 18:56:02 +0200 +Subject: [PATCH 2/5] ALSA: timer: Fix missing queue indices reset at + SNDRV_TIMER_IOCTL_SELECT + +snd_timer_user_tselect() reallocates the queue buffer dynamically, but +it forgot to reset its indices. Since the read may happen +concurrently with ioctl and snd_timer_user_tselect() allocates the +buffer via kmalloc(), this may lead to the leak of uninitialized +kernel-space data, as spotted via KMSAN: + + BUG: KMSAN: use of unitialized memory in snd_timer_user_read+0x6c4/0xa10 + CPU: 0 PID: 1037 Comm: probe Not tainted 4.11.0-rc5+ #2739 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + Call Trace: + __dump_stack lib/dump_stack.c:16 + dump_stack+0x143/0x1b0 lib/dump_stack.c:52 + kmsan_report+0x12a/0x180 mm/kmsan/kmsan.c:1007 + kmsan_check_memory+0xc2/0x140 mm/kmsan/kmsan.c:1086 + copy_to_user ./arch/x86/include/asm/uaccess.h:725 + snd_timer_user_read+0x6c4/0xa10 sound/core/timer.c:2004 + do_loop_readv_writev fs/read_write.c:716 + __do_readv_writev+0x94c/0x1380 fs/read_write.c:864 + do_readv_writev fs/read_write.c:894 + vfs_readv fs/read_write.c:908 + do_readv+0x52a/0x5d0 fs/read_write.c:934 + SYSC_readv+0xb6/0xd0 fs/read_write.c:1021 + SyS_readv+0x87/0xb0 fs/read_write.c:1018 + +This patch adds the missing reset of queue indices. Together with the +previous fix for the ioctl/read race, we cover the whole problem. + +Reported-by: Alexander Potapenko +Tested-by: Alexander Potapenko +Cc: +Signed-off-by: Takashi Iwai + +CVE-2017-1000380 + +(cherry-picked from commit ba3021b2c79b2fa9114f92790a99deb27a65b728) +Signed-off-by: Stefan Bader +Acked-by: Seth Forshee +Acked-by: Thadeu Lima de Souza Cascardo +Signed-off-by: Thadeu Lima de Souza Cascardo + +Signed-off-by: Thomas Lamprecht +--- + sound/core/timer.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 3c11a6983f54..e5ddc475dca4 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -1622,6 +1622,7 @@ static int snd_timer_user_tselect(struct file *file, + if (err < 0) + goto __err; + ++ tu->qhead = tu->qtail = tu->qused = 0; + kfree(tu->queue); + tu->queue = NULL; + kfree(tu->tqueue); +-- +2.11.0 + diff --git a/CVE-2017-1000380-ALSA-timer-Fix-race-between-read-and-ioctl.patch b/CVE-2017-1000380-ALSA-timer-Fix-race-between-read-and-ioctl.patch new file mode 100644 index 0000000..c6c197c --- /dev/null +++ b/CVE-2017-1000380-ALSA-timer-Fix-race-between-read-and-ioctl.patch @@ -0,0 +1,83 @@ +From 425e11483546f928109e5871a2c8b0fba3ddb3b4 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 21 Jun 2017 18:56:01 +0200 +Subject: [PATCH 1/5] ALSA: timer: Fix race between read and ioctl + +The read from ALSA timer device, the function snd_timer_user_tread(), +may access to an uninitialized struct snd_timer_user fields when the +read is concurrently performed while the ioctl like +snd_timer_user_tselect() is invoked. We have already fixed the races +among ioctls via a mutex, but we seem to have forgotten the race +between read vs ioctl. + +This patch simply applies (more exactly extends the already applied +range of) tu->ioctl_lock in snd_timer_user_tread() for closing the +race window. + +Reported-by: Alexander Potapenko +Tested-by: Alexander Potapenko +Cc: +Signed-off-by: Takashi Iwai + +CVE-2017-1000380 + +(cherry-picked from commit d11662f4f798b50d8c8743f433842c3e40fe3378) +Signed-off-by: Stefan Bader +Acked-by: Seth Forshee +Acked-by: Thadeu Lima de Souza Cascardo +Signed-off-by: Thadeu Lima de Souza Cascardo + +Signed-off-by: Thomas Lamprecht +--- + sound/core/timer.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/core/timer.c b/sound/core/timer.c +index ad153149b231..3c11a6983f54 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -1963,6 +1963,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, + + tu = file->private_data; + unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read); ++ mutex_lock(&tu->ioctl_lock); + spin_lock_irq(&tu->qlock); + while ((long)count - result >= unit) { + while (!tu->qused) { +@@ -1978,7 +1979,9 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, + add_wait_queue(&tu->qchange_sleep, &wait); + + spin_unlock_irq(&tu->qlock); ++ mutex_unlock(&tu->ioctl_lock); + schedule(); ++ mutex_lock(&tu->ioctl_lock); + spin_lock_irq(&tu->qlock); + + remove_wait_queue(&tu->qchange_sleep, &wait); +@@ -1998,7 +2001,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, + tu->qused--; + spin_unlock_irq(&tu->qlock); + +- mutex_lock(&tu->ioctl_lock); + if (tu->tread) { + if (copy_to_user(buffer, &tu->tqueue[qhead], + sizeof(struct snd_timer_tread))) +@@ -2008,7 +2010,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, + sizeof(struct snd_timer_read))) + err = -EFAULT; + } +- mutex_unlock(&tu->ioctl_lock); + + spin_lock_irq(&tu->qlock); + if (err < 0) +@@ -2018,6 +2019,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, + } + _error: + spin_unlock_irq(&tu->qlock); ++ mutex_unlock(&tu->ioctl_lock); + return result > 0 ? result : err; + } + +-- +2.11.0 + diff --git a/CVE-2017-7346-drm-vmwgfx-limit-the-number-of-mip-levels-in-vmw_gb_.patch b/CVE-2017-7346-drm-vmwgfx-limit-the-number-of-mip-levels-in-vmw_gb_.patch new file mode 100644 index 0000000..3f30a15 --- /dev/null +++ b/CVE-2017-7346-drm-vmwgfx-limit-the-number-of-mip-levels-in-vmw_gb_.patch @@ -0,0 +1,46 @@ +From ab13cf852828060a7d9550c05197e5303de7aefb Mon Sep 17 00:00:00 2001 +From: Vladis Dronov +Date: Wed, 14 Jun 2017 11:09:00 +0200 +Subject: [PATCH 4/5] drm/vmwgfx: limit the number of mip levels in + vmw_gb_surface_define_ioctl() + +CVE-2017-7346 + +The 'req->mip_levels' parameter in vmw_gb_surface_define_ioctl() is +a user-controlled 'uint32_t' value which is used as a loop count limit. +This can lead to a kernel lockup and DoS. Add check for 'req->mip_levels'. + +References: +https://bugzilla.redhat.com/show_bug.cgi?id=1437431 + +Cc: +Signed-off-by: Vladis Dronov +Reviewed-by: Sinclair Yeh + +(cherry picked from commit ee9c4e681ec4f58e42a83cb0c22a0289ade1aacf) +Signed-off-by: Po-Hsu Lin +Acked-by: Stefan Bader +Acked-by: Seth Forshee +Signed-off-by: Stefan Bader +Signed-off-by: Thomas Lamprecht +--- + drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index 8da50fce3b77..56b803384ea2 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -1280,6 +1280,9 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, + if (req->multisample_count != 0) + return -EINVAL; + ++ if (req->mip_levels > DRM_VMW_MAX_MIP_LEVELS) ++ return -EINVAL; ++ + if (unlikely(vmw_user_surface_size == 0)) + vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) + + 128; +-- +2.11.0 + diff --git a/CVE-2017-9605-drm-vmwgfx-Make-sure-backup_handle-is-always-valid.patch b/CVE-2017-9605-drm-vmwgfx-Make-sure-backup_handle-is-always-valid.patch new file mode 100644 index 0000000..243a32a --- /dev/null +++ b/CVE-2017-9605-drm-vmwgfx-Make-sure-backup_handle-is-always-valid.patch @@ -0,0 +1,68 @@ +From a2285dfad4c68beb9a8376fa2a2df905319b11fa Mon Sep 17 00:00:00 2001 +From: Sinclair Yeh +Date: Thu, 22 Jun 2017 17:28:14 +0200 +Subject: [PATCH 3/5] drm/vmwgfx: Make sure backup_handle is always valid + +When vmw_gb_surface_define_ioctl() is called with an existing buffer, +we end up returning an uninitialized variable in the backup_handle. + +The fix is to first initialize backup_handle to 0 just to be sure, and +second, when a user-provided buffer is found, we will use the +req->buffer_handle as the backup_handle. + +Cc: +Reported-by: Murray McAllister +Signed-off-by: Sinclair Yeh +Reviewed-by: Deepak Rawat + +CVE-2017-9605 + +(cherry picked from commit 07678eca2cf9c9a18584e546c2b2a0d0c9a3150c) +Signed-off-by: Stefan Bader +Acked-by: Colin Ian King +Acked-by: Po-Hsu Lin +Signed-off-by: Thadeu Lima de Souza Cascardo +Signed-off-by: Thomas Lamprecht +--- + drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index 05fa092c942b..8da50fce3b77 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -1275,7 +1275,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + int ret; + uint32_t size; +- uint32_t backup_handle; ++ uint32_t backup_handle = 0; + + if (req->multisample_count != 0) + return -EINVAL; +@@ -1315,12 +1315,16 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, + ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle, + &res->backup, + &user_srf->backup_base); +- if (ret == 0 && res->backup->base.num_pages * PAGE_SIZE < +- res->backup_size) { +- DRM_ERROR("Surface backup buffer is too small.\n"); +- vmw_dmabuf_unreference(&res->backup); +- ret = -EINVAL; +- goto out_unlock; ++ if (ret == 0) { ++ if (res->backup->base.num_pages * PAGE_SIZE < ++ res->backup_size) { ++ DRM_ERROR("Surface backup buffer is too small.\n"); ++ vmw_dmabuf_unreference(&res->backup); ++ ret = -EINVAL; ++ goto out_unlock; ++ } else { ++ backup_handle = req->buffer_handle; ++ } + } + } else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer) + ret = vmw_user_dmabuf_alloc(dev_priv, tfile, +-- +2.11.0 + diff --git a/Makefile b/Makefile index 806dcd4..9bd10ac 100644 --- a/Makefile +++ b/Makefile @@ -234,6 +234,11 @@ ${KERNEL_SRC}/README ${KERNEL_CFG_ORG}: ${KERNEL_SRC_SUBMODULE} | submodules cd ${KERNEL_SRC}; patch -p1 < ../kvm-dynamic-halt-polling-disable-default.patch cd ${KERNEL_SRC}; patch -p1 < ../cgroup-cpuset-add-cpuset.remap_cpus.patch cd ${KERNEL_SRC}; patch -p1 < ../0001-netfilter-nft_set_rbtree-handle-re-addition-element-.patch # DoS from within (unpriv) containers + cd ${KERNEL_SRC}; patch -p1 < ../CVE-2014-9900-net-Zeroing-the-structure-ethtool_wolinfo-in-ethtool.patch + cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-1000380-ALSA-timer-Fix-missing-queue-indices-reset-at-SNDRV_.patch + cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-1000380-ALSA-timer-Fix-race-between-read-and-ioctl.patch + cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-7346-drm-vmwgfx-limit-the-number-of-mip-levels-in-vmw_gb_.patch + cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-9605-drm-vmwgfx-Make-sure-backup_handle-is-always-valid.patch sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/' touch $@