summaryrefslogtreecommitdiff
path: root/sound/usb/card.c
diff options
context:
space:
mode:
authorHui Peng <benquike@gmail.com>2018-12-03 18:09:34 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-12-13 11:16:16 +0300
commita7e719ace75e4451b7958cb73cbc12c627760007 (patch)
tree5d566aede7b7c1eff6866db28634376f89a8e487 /sound/usb/card.c
parent86c257e05223a19a80882904ea5a14babb72eb26 (diff)
downloadlinux-a7e719ace75e4451b7958cb73cbc12c627760007.tar.xz
ALSA: usb-audio: Fix UAF decrement if card has no live interfaces in card.c
commit 5f8cf712582617d523120df67d392059eaf2fc4b upstream. If a USB sound card reports 0 interfaces, an error condition is triggered and the function usb_audio_probe errors out. In the error path, there was a use-after-free vulnerability where the memory object of the card was first freed, followed by a decrement of the number of active chips. Moving the decrement above the atomic_dec fixes the UAF. [ The original problem was introduced in 3.1 kernel, while it was developed in a different form. The Fixes tag below indicates the original commit but it doesn't mean that the patch is applicable cleanly. -- tiwai ] Fixes: 362e4e49abe5 ("ALSA: usb-audio - clear chip->probing on error exit") Reported-by: Hui Peng <benquike@gmail.com> Reported-by: Mathias Payer <mathias.payer@nebelwelt.net> Signed-off-by: Hui Peng <benquike@gmail.com> Signed-off-by: Mathias Payer <mathias.payer@nebelwelt.net> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound/usb/card.c')
-rw-r--r--sound/usb/card.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 2bfe4e80a6b9..a105947eaf55 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -682,9 +682,12 @@ static int usb_audio_probe(struct usb_interface *intf,
__error:
if (chip) {
+ /* chip->active is inside the chip->card object,
+ * decrement before memory is possibly returned.
+ */
+ atomic_dec(&chip->active);
if (!chip->num_interfaces)
snd_card_free(chip->card);
- atomic_dec(&chip->active);
}
mutex_unlock(&register_mutex);
return err;