From 11517177c55782761a22a6daab4e1569ebf0ef13 Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Tue, 27 Jan 2015 14:04:09 +0100 Subject: 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 --- .../linux/files/0001-ALSA-CVE-2014-4652.patch | 140 +++++++++++++++++++++ .../linux/files/0002-ALSA-CVE-2014-4653.patch | 92 ++++++++++++++ recipes-kernel/linux/linux-qoriq_3.12.bb | 2 + 3 files changed, 234 insertions(+) create mode 100644 recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch create mode 100644 recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch (limited to 'recipes-kernel/linux') diff --git a/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch b/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch new file mode 100644 index 0000000..0130768 --- /dev/null +++ b/recipes-kernel/linux/files/0001-ALSA-CVE-2014-4652.patch @@ -0,0 +1,140 @@ +From ed81e6b21790b717cda5f5bab2bdb07d2ce17ab1 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen +Date: Wed, 18 Jun 2014 13:32:31 +0200 +Subject: [PATCH] ALSA: control: Protect user controls against concurrent + access + +commit 07f4d9d74a04aa7c72c5dae0ef97565f28f17b92 upstream. + +The user-control put and get handlers as well as the tlv do not protect against +concurrent access from multiple threads. Since the state of the control is not +updated atomically it is possible that either two write operations or a write +and a read operation race against each other. Both can lead to arbitrary memory +disclosure. This patch introduces a new lock that protects user-controls from +concurrent access. Since applications typically access controls sequentially +than in parallel a single lock per card should be fine. + +This fixes CVE-2014-4652 +Upstream-Status: Backport + +Signed-off-by: Lars-Peter Clausen +Acked-by: Jaroslav Kysela +Signed-off-by: Takashi Iwai +Signed-off-by: Jiri Slaby +Signed-off-by: Sona Sarmadi +--- + include/sound/core.h | 2 ++ + sound/core/control.c | 31 +++++++++++++++++++++++++------ + sound/core/init.c | 1 + + 3 files changed, 28 insertions(+), 6 deletions(-) + +diff --git a/include/sound/core.h b/include/sound/core.h +index 2a14f1f..d6bc961 100644 +--- a/include/sound/core.h ++++ b/include/sound/core.h +@@ -121,6 +121,8 @@ struct snd_card { + int user_ctl_count; /* count of all user controls */ + struct list_head controls; /* all controls for this card */ + struct list_head ctl_files; /* active control files */ ++ struct mutex user_ctl_lock; /* protects user controls against ++ concurrent access */ + + struct snd_info_entry *proc_root; /* root for soundcard specific files */ + struct snd_info_entry *proc_id; /* the card id */ +diff --git a/sound/core/control.c b/sound/core/control.c +index d8aa206..183fab2 100644 +--- a/sound/core/control.c ++++ b/sound/core/control.c +@@ -992,6 +992,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, + + struct user_element { + struct snd_ctl_elem_info info; ++ struct snd_card *card; + void *elem_data; /* element data */ + unsigned long elem_data_size; /* size of element data in bytes */ + void *tlv_data; /* TLV data */ +@@ -1035,7 +1036,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, + { + struct user_element *ue = kcontrol->private_data; + ++ mutex_lock(&ue->card->user_ctl_lock); + memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); ++ mutex_unlock(&ue->card->user_ctl_lock); + return 0; + } + +@@ -1044,10 +1047,12 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, + { + int change; + struct user_element *ue = kcontrol->private_data; +- ++ ++ mutex_lock(&ue->card->user_ctl_lock); + change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; + if (change) + memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); ++ mutex_unlock(&ue->card->user_ctl_lock); + return change; + } + +@@ -1067,19 +1072,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, + new_data = memdup_user(tlv, size); + if (IS_ERR(new_data)) + return PTR_ERR(new_data); ++ mutex_lock(&ue->card->user_ctl_lock); + change = ue->tlv_data_size != size; + if (!change) + change = memcmp(ue->tlv_data, new_data, size); + kfree(ue->tlv_data); + ue->tlv_data = new_data; + ue->tlv_data_size = size; ++ mutex_unlock(&ue->card->user_ctl_lock); + } else { +- if (! ue->tlv_data_size || ! ue->tlv_data) +- return -ENXIO; +- if (size < ue->tlv_data_size) +- return -ENOSPC; ++ int ret = 0; ++ ++ mutex_lock(&ue->card->user_ctl_lock); ++ if (!ue->tlv_data_size || !ue->tlv_data) { ++ ret = -ENXIO; ++ goto err_unlock; ++ } ++ if (size < ue->tlv_data_size) { ++ ret = -ENOSPC; ++ goto err_unlock; ++ } + if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) +- return -EFAULT; ++ ret = -EFAULT; ++err_unlock: ++ mutex_unlock(&ue->card->user_ctl_lock); ++ if (ret) ++ return ret; + } + return change; + } +@@ -1211,6 +1229,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, + ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); + if (ue == NULL) + return -ENOMEM; ++ ue->card = card; + ue->info = *info; + ue->info.access = 0; + ue->elem_data = (char *)ue + sizeof(*ue); +diff --git a/sound/core/init.c b/sound/core/init.c +index d047851..b9268a5 100644 +--- a/sound/core/init.c ++++ b/sound/core/init.c +@@ -215,6 +215,7 @@ int snd_card_create(int idx, const char *xid, + INIT_LIST_HEAD(&card->devices); + init_rwsem(&card->controls_rwsem); + rwlock_init(&card->ctl_files_rwlock); ++ mutex_init(&card->user_ctl_lock); + INIT_LIST_HEAD(&card->controls); + INIT_LIST_HEAD(&card->ctl_files); + spin_lock_init(&card->files_lock); +-- +1.9.1 + diff --git a/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch b/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch new file mode 100644 index 0000000..8612d74 --- /dev/null +++ b/recipes-kernel/linux/files/0002-ALSA-CVE-2014-4653.patch @@ -0,0 +1,92 @@ +From 0bf595fd311aa4d6e82c43879f2c0d0650e83271 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen +Date: Wed, 18 Jun 2014 13:32:33 +0200 +Subject: [PATCH] ALSA: control: Don't access controls outside of protected + regions + +commit fd9f26e4eca5d08a27d12c0933fceef76ed9663d upstream. + +A control that is visible on the card->controls list can be freed at any time. +This means we must not access any of its memory while not holding the +controls_rw_lock. Otherwise we risk a use after free access. + +This fixes CVE-2014-4653 +Upstream-Status: Backport + +Signed-off-by: Lars-Peter Clausen +Acked-by: Jaroslav Kysela +Signed-off-by: Takashi Iwai +Signed-off-by: Jiri Slaby +Signed-off-by: Sona Sarmadi +--- + sound/core/control.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/sound/core/control.c b/sound/core/control.c +index 15bc844..d4a597f 100644 +--- a/sound/core/control.c ++++ b/sound/core/control.c +@@ -331,6 +331,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) + { + struct snd_ctl_elem_id id; + unsigned int idx; ++ unsigned int count; + int err = -EINVAL; + + if (! kcontrol) +@@ -359,8 +360,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) + card->controls_count += kcontrol->count; + kcontrol->id.numid = card->last_numid + 1; + card->last_numid += kcontrol->count; ++ count = kcontrol->count; + up_write(&card->controls_rwsem); +- for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) ++ for (idx = 0; idx < count; idx++, id.index++, id.numid++) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); + return 0; + +@@ -389,6 +391,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, + bool add_on_replace) + { + struct snd_ctl_elem_id id; ++ unsigned int count; + unsigned int idx; + struct snd_kcontrol *old; + int ret; +@@ -424,8 +427,9 @@ add: + card->controls_count += kcontrol->count; + kcontrol->id.numid = card->last_numid + 1; + card->last_numid += kcontrol->count; ++ count = kcontrol->count; + up_write(&card->controls_rwsem); +- for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) ++ for (idx = 0; idx < count; idx++, id.index++, id.numid++) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); + return 0; + +@@ -898,9 +902,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, + result = kctl->put(kctl, control); + } + if (result > 0) { ++ struct snd_ctl_elem_id id = control->id; + up_read(&card->controls_rwsem); +- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, +- &control->id); ++ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); + return 0; + } + } +@@ -1334,8 +1338,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, + } + err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); + if (err > 0) { ++ struct snd_ctl_elem_id id = kctl->id; + up_read(&card->controls_rwsem); +- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); ++ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); + return 0; + } + } else { +-- +1.9.1 + diff --git a/recipes-kernel/linux/linux-qoriq_3.12.bb b/recipes-kernel/linux/linux-qoriq_3.12.bb index bbbf4ba..90ccedd 100644 --- a/recipes-kernel/linux/linux-qoriq_3.12.bb +++ b/recipes-kernel/linux/linux-qoriq_3.12.bb @@ -23,6 +23,8 @@ SRC_URI = "git://git.freescale.com/ppc/sdk/linux.git;nobranch=1 \ file://0002-net-sctp-CVE-2014-3687.patch \ file://0003-net-sctp-CVE-2014-3688.patch \ file://auditsc-CVE-2014-3917.patch \ + file://0001-ALSA-CVE-2014-4652.patch \ + file://0002-ALSA-CVE-2014-4653.patch \ " SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229" -- cgit v1.2.3-54-g00ecf