diff options
author | Sona Sarmadi <sona.sarmadi@enea.com> | 2016-04-05 14:18:37 +0300 |
---|---|---|
committer | Stefan Sicleru <stefan.sicleru@enea.com> | 2016-04-05 13:39:49 +0200 |
commit | fcf7696db59deb585129b0d4739ba6eab499617e (patch) | |
tree | 417d5bb209ea455fdea202a58705746450f8474d | |
parent | e370b0b1ce8e53642fe1fbef6c90548e0d7763ad (diff) | |
download | meta-enea-fcf7696db59deb585129b0d4739ba6eab499617e.tar.gz |
kernel/ALSA: CVE-2016-2546
Fixes an open race in ALSA timer ioctls (in the linux-yocto-3.14).
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=7510c77227536d85013016289c96dd1fe212db77
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 <sona.sarmadi@enea.com>
-rw-r--r-- | recipes-kernel/linux/linux-yocto-3.14/ALSA-CVE-2016-2546.patch | 128 | ||||
-rw-r--r-- | recipes-kernel/linux/linux-yocto_3.14.bbappend | 1 |
2 files changed, 129 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-yocto-3.14/ALSA-CVE-2016-2546.patch b/recipes-kernel/linux/linux-yocto-3.14/ALSA-CVE-2016-2546.patch new file mode 100644 index 0000000..1e6f0c8 --- /dev/null +++ b/recipes-kernel/linux/linux-yocto-3.14/ALSA-CVE-2016-2546.patch | |||
@@ -0,0 +1,128 @@ | |||
1 | From 7510c77227536d85013016289c96dd1fe212db77 Mon Sep 17 00:00:00 2001 | ||
2 | From: Takashi Iwai <tiwai@suse.de> | ||
3 | Date: Wed, 13 Jan 2016 17:48:01 +0100 | ||
4 | Subject: ALSA: timer: Fix race among timer ioctls | ||
5 | |||
6 | commit af368027a49a751d6ff4ee9e3f9961f35bb4fede upstream. | ||
7 | |||
8 | ALSA timer ioctls have an open race and this may lead to a | ||
9 | use-after-free of timer instance object. A simplistic fix is to make | ||
10 | each ioctl exclusive. We have already tread_sem for controlling the | ||
11 | tread, and extend this as a global mutex to be applied to each ioctl. | ||
12 | |||
13 | The downside is, of course, the worse concurrency. But these ioctls | ||
14 | aren't to be parallel accessible, in anyway, so it should be fine to | ||
15 | serialize there. | ||
16 | |||
17 | CVE: CVE-2016-2546 | ||
18 | Upstream-Status: Backport | ||
19 | |||
20 | Reported-by: Dmitry Vyukov <dvyukov@google.com> | ||
21 | Tested-by: Dmitry Vyukov <dvyukov@google.com> | ||
22 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | ||
23 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
24 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
25 | --- | ||
26 | sound/core/timer.c | 32 +++++++++++++++++++------------- | ||
27 | 1 file changed, 19 insertions(+), 13 deletions(-) | ||
28 | |||
29 | diff --git a/sound/core/timer.c b/sound/core/timer.c | ||
30 | index 38a137d..1d54617 100644 | ||
31 | --- a/sound/core/timer.c | ||
32 | +++ b/sound/core/timer.c | ||
33 | @@ -73,7 +73,7 @@ struct snd_timer_user { | ||
34 | struct timespec tstamp; /* trigger tstamp */ | ||
35 | wait_queue_head_t qchange_sleep; | ||
36 | struct fasync_struct *fasync; | ||
37 | - struct mutex tread_sem; | ||
38 | + struct mutex ioctl_lock; | ||
39 | }; | ||
40 | |||
41 | /* list of timers */ | ||
42 | @@ -1266,7 +1266,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) | ||
43 | return -ENOMEM; | ||
44 | spin_lock_init(&tu->qlock); | ||
45 | init_waitqueue_head(&tu->qchange_sleep); | ||
46 | - mutex_init(&tu->tread_sem); | ||
47 | + mutex_init(&tu->ioctl_lock); | ||
48 | tu->ticks = 1; | ||
49 | tu->queue_size = 128; | ||
50 | tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), | ||
51 | @@ -1286,8 +1286,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) | ||
52 | if (file->private_data) { | ||
53 | tu = file->private_data; | ||
54 | file->private_data = NULL; | ||
55 | + mutex_lock(&tu->ioctl_lock); | ||
56 | if (tu->timeri) | ||
57 | snd_timer_close(tu->timeri); | ||
58 | + mutex_unlock(&tu->ioctl_lock); | ||
59 | kfree(tu->queue); | ||
60 | kfree(tu->tqueue); | ||
61 | kfree(tu); | ||
62 | @@ -1525,7 +1527,6 @@ static int snd_timer_user_tselect(struct file *file, | ||
63 | int err = 0; | ||
64 | |||
65 | tu = file->private_data; | ||
66 | - mutex_lock(&tu->tread_sem); | ||
67 | if (tu->timeri) { | ||
68 | snd_timer_close(tu->timeri); | ||
69 | tu->timeri = NULL; | ||
70 | @@ -1569,7 +1570,6 @@ static int snd_timer_user_tselect(struct file *file, | ||
71 | } | ||
72 | |||
73 | __err: | ||
74 | - mutex_unlock(&tu->tread_sem); | ||
75 | return err; | ||
76 | } | ||
77 | |||
78 | @@ -1782,7 +1782,7 @@ enum { | ||
79 | SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), | ||
80 | }; | ||
81 | |||
82 | -static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, | ||
83 | +static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, | ||
84 | unsigned long arg) | ||
85 | { | ||
86 | struct snd_timer_user *tu; | ||
87 | @@ -1799,17 +1799,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, | ||
88 | { | ||
89 | int xarg; | ||
90 | |||
91 | - mutex_lock(&tu->tread_sem); | ||
92 | - if (tu->timeri) { /* too late */ | ||
93 | - mutex_unlock(&tu->tread_sem); | ||
94 | + if (tu->timeri) /* too late */ | ||
95 | return -EBUSY; | ||
96 | - } | ||
97 | - if (get_user(xarg, p)) { | ||
98 | - mutex_unlock(&tu->tread_sem); | ||
99 | + if (get_user(xarg, p)) | ||
100 | return -EFAULT; | ||
101 | - } | ||
102 | tu->tread = xarg ? 1 : 0; | ||
103 | - mutex_unlock(&tu->tread_sem); | ||
104 | return 0; | ||
105 | } | ||
106 | case SNDRV_TIMER_IOCTL_GINFO: | ||
107 | @@ -1842,6 +1836,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, | ||
108 | return -ENOTTY; | ||
109 | } | ||
110 | |||
111 | +static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, | ||
112 | + unsigned long arg) | ||
113 | +{ | ||
114 | + struct snd_timer_user *tu = file->private_data; | ||
115 | + long ret; | ||
116 | + | ||
117 | + mutex_lock(&tu->ioctl_lock); | ||
118 | + ret = __snd_timer_user_ioctl(file, cmd, arg); | ||
119 | + mutex_unlock(&tu->ioctl_lock); | ||
120 | + return ret; | ||
121 | +} | ||
122 | + | ||
123 | static int snd_timer_user_fasync(int fd, struct file * file, int on) | ||
124 | { | ||
125 | struct snd_timer_user *tu; | ||
126 | -- | ||
127 | cgit v0.12 | ||
128 | |||
diff --git a/recipes-kernel/linux/linux-yocto_3.14.bbappend b/recipes-kernel/linux/linux-yocto_3.14.bbappend index 82135a1..54a092d 100644 --- a/recipes-kernel/linux/linux-yocto_3.14.bbappend +++ b/recipes-kernel/linux/linux-yocto_3.14.bbappend | |||
@@ -26,4 +26,5 @@ SRC_URI += "file://HID_CVE_patches/0005-HID-steelseries-validate-output-report-d | |||
26 | file://virtio-net-CVE-2015-5156.patch \ | 26 | file://virtio-net-CVE-2015-5156.patch \ |
27 | file://ipc-CVE-2015-7613.patch \ | 27 | file://ipc-CVE-2015-7613.patch \ |
28 | file://net-unix-CVE-2013-7446.patch \ | 28 | file://net-unix-CVE-2013-7446.patch \ |
29 | file://ALSA-CVE-2016-2546.patch \ | ||
29 | " | 30 | " |