[meta-freescale] [meta-fsl-ppc][PATCH 3/5] ALSA: CVE-2014-4652 CVE-2014-4653

Sona Sarmadi sona.sarmadi at enea.com
Tue Jan 27 05:04:09 PST 2015


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 at enea.com>
---
 .../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

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 <lars at metafoo.de>
+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 <lars at metafoo.de>
+Acked-by: Jaroslav Kysela <perex at perex.cz>
+Signed-off-by: Takashi Iwai <tiwai at suse.de>
+Signed-off-by: Jiri Slaby <jslaby at suse.cz>
+Signed-off-by: Sona Sarmadi <sona.sarmadi at enea.com>
+---
+ 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 <lars at metafoo.de>
+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 <lars at metafoo.de>
+Acked-by: Jaroslav Kysela <perex at perex.cz>
+Signed-off-by: Takashi Iwai <tiwai at suse.de>
+Signed-off-by: Jiri Slaby <jslaby at suse.cz>
+Signed-off-by: Sona Sarmadi <sona.sarmadi at enea.com>
+---
+ 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"
 
-- 
1.9.1



More information about the meta-freescale mailing list