diff options
author | Sona Sarmadi <sona.sarmadi@enea.com> | 2015-01-27 14:04:09 +0100 |
---|---|---|
committer | Zhenhua Luo <zhenhua.luo@freescale.com> | 2015-02-03 10:09:23 +0800 |
commit | 6a6c9c5fdab04e8c78d4d7a72a359cb03bb1cdd0 (patch) | |
tree | f79bbd810749ed5c22c483c881b21686420756e7 | |
parent | f4a55466f032850b4ca8c495d76d06d18d77fb00 (diff) | |
download | meta-freescale-6a6c9c5fdab04e8c78d4d7a72a359cb03bb1cdd0.tar.gz |
ALSA: CVE-2014-4652 CVE-2014-4653
CVE-2014-4652
Protect user controls against concurrent access
CVE-2014-4653
Don't access controls outside of protected regions
Reference:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4652
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4653
Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
3 files changed, 234 insertions, 0 deletions
diff --git a/meta-fsl-ppc/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch b/meta-fsl-ppc/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch new file mode 100644 index 00000000..01307688 --- /dev/null +++ b/meta-fsl-ppc/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch | |||
@@ -0,0 +1,140 @@ | |||
1 | From ed81e6b21790b717cda5f5bab2bdb07d2ce17ab1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Lars-Peter Clausen <lars@metafoo.de> | ||
3 | Date: Wed, 18 Jun 2014 13:32:31 +0200 | ||
4 | Subject: [PATCH] ALSA: control: Protect user controls against concurrent | ||
5 | access | ||
6 | |||
7 | commit 07f4d9d74a04aa7c72c5dae0ef97565f28f17b92 upstream. | ||
8 | |||
9 | The user-control put and get handlers as well as the tlv do not protect against | ||
10 | concurrent access from multiple threads. Since the state of the control is not | ||
11 | updated atomically it is possible that either two write operations or a write | ||
12 | and a read operation race against each other. Both can lead to arbitrary memory | ||
13 | disclosure. This patch introduces a new lock that protects user-controls from | ||
14 | concurrent access. Since applications typically access controls sequentially | ||
15 | than in parallel a single lock per card should be fine. | ||
16 | |||
17 | This fixes CVE-2014-4652 | ||
18 | Upstream-Status: Backport | ||
19 | |||
20 | Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> | ||
21 | Acked-by: Jaroslav Kysela <perex@perex.cz> | ||
22 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | ||
23 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
24 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
25 | --- | ||
26 | include/sound/core.h | 2 ++ | ||
27 | sound/core/control.c | 31 +++++++++++++++++++++++++------ | ||
28 | sound/core/init.c | 1 + | ||
29 | 3 files changed, 28 insertions(+), 6 deletions(-) | ||
30 | |||
31 | diff --git a/include/sound/core.h b/include/sound/core.h | ||
32 | index 2a14f1f..d6bc961 100644 | ||
33 | --- a/include/sound/core.h | ||
34 | +++ b/include/sound/core.h | ||
35 | @@ -121,6 +121,8 @@ struct snd_card { | ||
36 | int user_ctl_count; /* count of all user controls */ | ||
37 | struct list_head controls; /* all controls for this card */ | ||
38 | struct list_head ctl_files; /* active control files */ | ||
39 | + struct mutex user_ctl_lock; /* protects user controls against | ||
40 | + concurrent access */ | ||
41 | |||
42 | struct snd_info_entry *proc_root; /* root for soundcard specific files */ | ||
43 | struct snd_info_entry *proc_id; /* the card id */ | ||
44 | diff --git a/sound/core/control.c b/sound/core/control.c | ||
45 | index d8aa206..183fab2 100644 | ||
46 | --- a/sound/core/control.c | ||
47 | +++ b/sound/core/control.c | ||
48 | @@ -992,6 +992,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, | ||
49 | |||
50 | struct user_element { | ||
51 | struct snd_ctl_elem_info info; | ||
52 | + struct snd_card *card; | ||
53 | void *elem_data; /* element data */ | ||
54 | unsigned long elem_data_size; /* size of element data in bytes */ | ||
55 | void *tlv_data; /* TLV data */ | ||
56 | @@ -1035,7 +1036,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, | ||
57 | { | ||
58 | struct user_element *ue = kcontrol->private_data; | ||
59 | |||
60 | + mutex_lock(&ue->card->user_ctl_lock); | ||
61 | memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); | ||
62 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | @@ -1044,10 +1047,12 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, | ||
67 | { | ||
68 | int change; | ||
69 | struct user_element *ue = kcontrol->private_data; | ||
70 | - | ||
71 | + | ||
72 | + mutex_lock(&ue->card->user_ctl_lock); | ||
73 | change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; | ||
74 | if (change) | ||
75 | memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); | ||
76 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
77 | return change; | ||
78 | } | ||
79 | |||
80 | @@ -1067,19 +1072,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, | ||
81 | new_data = memdup_user(tlv, size); | ||
82 | if (IS_ERR(new_data)) | ||
83 | return PTR_ERR(new_data); | ||
84 | + mutex_lock(&ue->card->user_ctl_lock); | ||
85 | change = ue->tlv_data_size != size; | ||
86 | if (!change) | ||
87 | change = memcmp(ue->tlv_data, new_data, size); | ||
88 | kfree(ue->tlv_data); | ||
89 | ue->tlv_data = new_data; | ||
90 | ue->tlv_data_size = size; | ||
91 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
92 | } else { | ||
93 | - if (! ue->tlv_data_size || ! ue->tlv_data) | ||
94 | - return -ENXIO; | ||
95 | - if (size < ue->tlv_data_size) | ||
96 | - return -ENOSPC; | ||
97 | + int ret = 0; | ||
98 | + | ||
99 | + mutex_lock(&ue->card->user_ctl_lock); | ||
100 | + if (!ue->tlv_data_size || !ue->tlv_data) { | ||
101 | + ret = -ENXIO; | ||
102 | + goto err_unlock; | ||
103 | + } | ||
104 | + if (size < ue->tlv_data_size) { | ||
105 | + ret = -ENOSPC; | ||
106 | + goto err_unlock; | ||
107 | + } | ||
108 | if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) | ||
109 | - return -EFAULT; | ||
110 | + ret = -EFAULT; | ||
111 | +err_unlock: | ||
112 | + mutex_unlock(&ue->card->user_ctl_lock); | ||
113 | + if (ret) | ||
114 | + return ret; | ||
115 | } | ||
116 | return change; | ||
117 | } | ||
118 | @@ -1211,6 +1229,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | ||
119 | ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); | ||
120 | if (ue == NULL) | ||
121 | return -ENOMEM; | ||
122 | + ue->card = card; | ||
123 | ue->info = *info; | ||
124 | ue->info.access = 0; | ||
125 | ue->elem_data = (char *)ue + sizeof(*ue); | ||
126 | diff --git a/sound/core/init.c b/sound/core/init.c | ||
127 | index d047851..b9268a5 100644 | ||
128 | --- a/sound/core/init.c | ||
129 | +++ b/sound/core/init.c | ||
130 | @@ -215,6 +215,7 @@ int snd_card_create(int idx, const char *xid, | ||
131 | INIT_LIST_HEAD(&card->devices); | ||
132 | init_rwsem(&card->controls_rwsem); | ||
133 | rwlock_init(&card->ctl_files_rwlock); | ||
134 | + mutex_init(&card->user_ctl_lock); | ||
135 | INIT_LIST_HEAD(&card->controls); | ||
136 | INIT_LIST_HEAD(&card->ctl_files); | ||
137 | spin_lock_init(&card->files_lock); | ||
138 | -- | ||
139 | 1.9.1 | ||
140 | |||
diff --git a/meta-fsl-ppc/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch b/meta-fsl-ppc/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch new file mode 100644 index 00000000..8612d74a --- /dev/null +++ b/meta-fsl-ppc/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch | |||
@@ -0,0 +1,92 @@ | |||
1 | From 0bf595fd311aa4d6e82c43879f2c0d0650e83271 Mon Sep 17 00:00:00 2001 | ||
2 | From: Lars-Peter Clausen <lars@metafoo.de> | ||
3 | Date: Wed, 18 Jun 2014 13:32:33 +0200 | ||
4 | Subject: [PATCH] ALSA: control: Don't access controls outside of protected | ||
5 | regions | ||
6 | |||
7 | commit fd9f26e4eca5d08a27d12c0933fceef76ed9663d upstream. | ||
8 | |||
9 | A control that is visible on the card->controls list can be freed at any time. | ||
10 | This means we must not access any of its memory while not holding the | ||
11 | controls_rw_lock. Otherwise we risk a use after free access. | ||
12 | |||
13 | This fixes CVE-2014-4653 | ||
14 | Upstream-Status: Backport | ||
15 | |||
16 | Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> | ||
17 | Acked-by: Jaroslav Kysela <perex@perex.cz> | ||
18 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | ||
19 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
20 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
21 | --- | ||
22 | sound/core/control.c | 15 ++++++++++----- | ||
23 | 1 file changed, 10 insertions(+), 5 deletions(-) | ||
24 | |||
25 | diff --git a/sound/core/control.c b/sound/core/control.c | ||
26 | index 15bc844..d4a597f 100644 | ||
27 | --- a/sound/core/control.c | ||
28 | +++ b/sound/core/control.c | ||
29 | @@ -331,6 +331,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | ||
30 | { | ||
31 | struct snd_ctl_elem_id id; | ||
32 | unsigned int idx; | ||
33 | + unsigned int count; | ||
34 | int err = -EINVAL; | ||
35 | |||
36 | if (! kcontrol) | ||
37 | @@ -359,8 +360,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | ||
38 | card->controls_count += kcontrol->count; | ||
39 | kcontrol->id.numid = card->last_numid + 1; | ||
40 | card->last_numid += kcontrol->count; | ||
41 | + count = kcontrol->count; | ||
42 | up_write(&card->controls_rwsem); | ||
43 | - for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | ||
44 | + for (idx = 0; idx < count; idx++, id.index++, id.numid++) | ||
45 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | ||
46 | return 0; | ||
47 | |||
48 | @@ -389,6 +391,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, | ||
49 | bool add_on_replace) | ||
50 | { | ||
51 | struct snd_ctl_elem_id id; | ||
52 | + unsigned int count; | ||
53 | unsigned int idx; | ||
54 | struct snd_kcontrol *old; | ||
55 | int ret; | ||
56 | @@ -424,8 +427,9 @@ add: | ||
57 | card->controls_count += kcontrol->count; | ||
58 | kcontrol->id.numid = card->last_numid + 1; | ||
59 | card->last_numid += kcontrol->count; | ||
60 | + count = kcontrol->count; | ||
61 | up_write(&card->controls_rwsem); | ||
62 | - for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | ||
63 | + for (idx = 0; idx < count; idx++, id.index++, id.numid++) | ||
64 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | ||
65 | return 0; | ||
66 | |||
67 | @@ -898,9 +902,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, | ||
68 | result = kctl->put(kctl, control); | ||
69 | } | ||
70 | if (result > 0) { | ||
71 | + struct snd_ctl_elem_id id = control->id; | ||
72 | up_read(&card->controls_rwsem); | ||
73 | - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
74 | - &control->id); | ||
75 | + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); | ||
76 | return 0; | ||
77 | } | ||
78 | } | ||
79 | @@ -1334,8 +1338,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, | ||
80 | } | ||
81 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); | ||
82 | if (err > 0) { | ||
83 | + struct snd_ctl_elem_id id = kctl->id; | ||
84 | up_read(&card->controls_rwsem); | ||
85 | - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); | ||
86 | + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); | ||
87 | return 0; | ||
88 | } | ||
89 | } else { | ||
90 | -- | ||
91 | 1.9.1 | ||
92 | |||
diff --git a/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb b/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb index bbbf4ba7..90ccedd9 100644 --- a/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb +++ b/meta-fsl-ppc/recipes-kernel/linux/linux-qoriq_3.12.bb | |||
@@ -23,6 +23,8 @@ SRC_URI = "git://git.freescale.com/ppc/sdk/linux.git;nobranch=1 \ | |||
23 | file://0002-net-sctp-CVE-2014-3687.patch \ | 23 | file://0002-net-sctp-CVE-2014-3687.patch \ |
24 | file://0003-net-sctp-CVE-2014-3688.patch \ | 24 | file://0003-net-sctp-CVE-2014-3688.patch \ |
25 | file://auditsc-CVE-2014-3917.patch \ | 25 | file://auditsc-CVE-2014-3917.patch \ |
26 | file://0001-ALSA-CVE-2014-4652.patch \ | ||
27 | file://0002-ALSA-CVE-2014-4653.patch \ | ||
26 | " | 28 | " |
27 | SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229" | 29 | SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229" |
28 | 30 | ||