From 95e2d54d188fa653d9075782a3e431925829c297 Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Tue, 5 Apr 2016 13:55:28 +0200 Subject: kernel/ALSA: CVE-2016-2546 Fixes an open race in ALSA timer ioctls. This flaw may lead to a use-after-free of timer instance object. Upstream patch: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ patch/?id=ac905ca58370789645e813d8abfa5871c93e9e36 References: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-2546 http://seclists.org/oss-sec/2016/q1/133 Signed-off-by: Sona Sarmadi Signed-off-by: Tudor Florea --- .../linux-hierofalcon/ALSA-CVE-2016-2546.patch | 128 +++++++++++++++++++++ recipes-kernel/linux/linux-hierofalcon_3.19.bb | 1 + recipes-kernel/linux/linux-hierofalcon_4.1.bb | 1 + 3 files changed, 130 insertions(+) create mode 100644 recipes-kernel/linux/linux-hierofalcon/ALSA-CVE-2016-2546.patch diff --git a/recipes-kernel/linux/linux-hierofalcon/ALSA-CVE-2016-2546.patch b/recipes-kernel/linux/linux-hierofalcon/ALSA-CVE-2016-2546.patch new file mode 100644 index 0000000..c17a22f --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon/ALSA-CVE-2016-2546.patch @@ -0,0 +1,128 @@ +From ac905ca58370789645e813d8abfa5871c93e9e36 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 13 Jan 2016 17:48:01 +0100 +Subject: ALSA: timer: Fix race among timer ioctls + +commit af368027a49a751d6ff4ee9e3f9961f35bb4fede upstream. + +ALSA timer ioctls have an open race and this may lead to a +use-after-free of timer instance object. A simplistic fix is to make +each ioctl exclusive. We have already tread_sem for controlling the +tread, and extend this as a global mutex to be applied to each ioctl. + +The downside is, of course, the worse concurrency. But these ioctls +aren't to be parallel accessible, in anyway, so it should be fine to +serialize there. + +CVE: CVE-2016-2546 +Upstream-Status: Backport + +Reported-by: Dmitry Vyukov +Tested-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sona Sarmadi +--- + sound/core/timer.c | 32 +++++++++++++++++++------------- + 1 file changed, 19 insertions(+), 13 deletions(-) + +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 149d4f2..f5ec1ba 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -73,7 +73,7 @@ struct snd_timer_user { + struct timespec tstamp; /* trigger tstamp */ + wait_queue_head_t qchange_sleep; + struct fasync_struct *fasync; +- struct mutex tread_sem; ++ struct mutex ioctl_lock; + }; + + /* list of timers */ +@@ -1263,7 +1263,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) + return -ENOMEM; + spin_lock_init(&tu->qlock); + init_waitqueue_head(&tu->qchange_sleep); +- mutex_init(&tu->tread_sem); ++ mutex_init(&tu->ioctl_lock); + tu->ticks = 1; + tu->queue_size = 128; + tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), +@@ -1283,8 +1283,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) + if (file->private_data) { + tu = file->private_data; + file->private_data = NULL; ++ mutex_lock(&tu->ioctl_lock); + if (tu->timeri) + snd_timer_close(tu->timeri); ++ mutex_unlock(&tu->ioctl_lock); + kfree(tu->queue); + kfree(tu->tqueue); + kfree(tu); +@@ -1522,7 +1524,6 @@ static int snd_timer_user_tselect(struct file *file, + int err = 0; + + tu = file->private_data; +- mutex_lock(&tu->tread_sem); + if (tu->timeri) { + snd_timer_close(tu->timeri); + tu->timeri = NULL; +@@ -1566,7 +1567,6 @@ static int snd_timer_user_tselect(struct file *file, + } + + __err: +- mutex_unlock(&tu->tread_sem); + return err; + } + +@@ -1779,7 +1779,7 @@ enum { + SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), + }; + +-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, ++static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) + { + struct snd_timer_user *tu; +@@ -1796,17 +1796,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, + { + int xarg; + +- mutex_lock(&tu->tread_sem); +- if (tu->timeri) { /* too late */ +- mutex_unlock(&tu->tread_sem); ++ if (tu->timeri) /* too late */ + return -EBUSY; +- } +- if (get_user(xarg, p)) { +- mutex_unlock(&tu->tread_sem); ++ if (get_user(xarg, p)) + return -EFAULT; +- } + tu->tread = xarg ? 1 : 0; +- mutex_unlock(&tu->tread_sem); + return 0; + } + case SNDRV_TIMER_IOCTL_GINFO: +@@ -1839,6 +1833,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, + return -ENOTTY; + } + ++static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct snd_timer_user *tu = file->private_data; ++ long ret; ++ ++ mutex_lock(&tu->ioctl_lock); ++ ret = __snd_timer_user_ioctl(file, cmd, arg); ++ mutex_unlock(&tu->ioctl_lock); ++ return ret; ++} ++ + static int snd_timer_user_fasync(int fd, struct file * file, int on) + { + struct snd_timer_user *tu; +-- +cgit v0.12 + diff --git a/recipes-kernel/linux/linux-hierofalcon_3.19.bb b/recipes-kernel/linux/linux-hierofalcon_3.19.bb index 92f6664..d56f1ff 100644 --- a/recipes-kernel/linux/linux-hierofalcon_3.19.bb +++ b/recipes-kernel/linux/linux-hierofalcon_3.19.bb @@ -34,6 +34,7 @@ SRC_URI = "git://git.yoctoproject.org/linux-yocto-3.19;branch="standard/qemuarm6 file://virtio-net-CVE-2015-5156.patch \ file://ipc-CVE-2015-7613.patch \ file://net-unix-CVE-2013-7446.patch \ + file://ALSA-CVE-2016-2546.patch \ " S = "${WORKDIR}/git" diff --git a/recipes-kernel/linux/linux-hierofalcon_4.1.bb b/recipes-kernel/linux/linux-hierofalcon_4.1.bb index 1227c71..2141668 100644 --- a/recipes-kernel/linux/linux-hierofalcon_4.1.bb +++ b/recipes-kernel/linux/linux-hierofalcon_4.1.bb @@ -35,6 +35,7 @@ SRC_URI = "git://git.yoctoproject.org/linux-yocto-4.1;branch="standard/qemuarm64 file://net-unix-CVE-2013-7446.patch \ file://usb-CVE-2015-8816.patch \ file://bpf-CVE-2016-2383.patch \ + file://ALSA-CVE-2016-2546.patch \ " S = "${WORKDIR}/git" -- cgit v1.2.3-54-g00ecf