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 000000000..013076885 --- /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 000000000..8612d74a7 --- /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 bbbf4ba71..90ccedd91 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 | ||
