FAILED: patch "[PATCH] ALSA: mixer: oss: Fix racy access to slots" failed to apply to 4.14-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 411cef6adfb38a5bb6bd9af3941b28198e7fb680 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <[email protected]>
Date: Wed, 20 Oct 2021 18:48:46 +0200
Subject: [PATCH] ALSA: mixer: oss: Fix racy access to slots
The OSS mixer can reassign the mapping slots dynamically via proc file. Although the addition and deletion of those slots are protected by mixer->reg_mutex, the access to slots aren't, hence this may cause UAF when the slots in use are deleted concurrently.
This patch applies the mixer->reg_mutex in all appropriate code paths (i.e. the ioctl functions) that may access slots.
sound/core/oss/mixer_oss.c +33 -11
@@ -130,11 +130,13 @@ static int snd_mixer_oss_devmask(struct snd_mixer_oss_file *fmixer)if (mixer ==NULL )return -EIO ; +mutex_lock (&mixer->reg_mutex);for (chn =0 ; chn <31 ; chn++) { pslot = &mixer->slots[chn];if (pslot->put_volume || pslot->put_recsrc) result |=1 << chn; } +mutex_unlock (&mixer->reg_mutex);return result; }
@@ -146,11 +148,13 @@ static int snd_mixer_oss_stereodevs(struct snd_mixer_oss_file *fmixer)if (mixer ==NULL )return -EIO ; +mutex_lock (&mixer->reg_mutex);for (chn =0 ; chn <31 ; chn++) { pslot = &mixer->slots[chn];if (pslot->put_volume && pslot->stereo) result |=1 << chn; } +mutex_unlock (&mixer->reg_mutex);return result; }
@@ -161,6 +165,7 @@ static int snd_mixer_oss_recmask(struct snd_mixer_oss_file *fmixer)if (mixer ==NULL )return -EIO ; +mutex_lock (&mixer->reg_mutex);if (mixer->put_recsrc && mixer->get_recsrc) {/* exclusive */ result = mixer->mask_recsrc; }else {
@@ -172,6 +177,7 @@ static int snd_mixer_oss_recmask(struct snd_mixer_oss_file *fmixer) result |=1 << chn; } } +mutex_unlock (&mixer->reg_mutex);return result; }
@@ -182,12 +188,12 @@ static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer)if (mixer ==NULL )return -EIO ; +mutex_lock (&mixer->reg_mutex);if (mixer->put_recsrc && mixer->get_recsrc) {/* exclusive */ -int err;unsigned int index; - err = mixer->get_recsrc (fmixer, &index); -if (err <0 ) -return err; + result = mixer->get_recsrc (fmixer, &index); +if (result <0 ) + goto unlock; result =1 << index; }else {struct snd_mixer_oss_slot *pslot;
@@ -202,7 +208,10 @@ static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer) } } } -return mixer->oss_recsrc = result; + mixer->oss_recsrc = result; + unlock: +mutex_unlock (&mixer->reg_mutex); +return result; }static int snd_mixer_oss_set_recsrc (struct snd_mixer_oss_file *fmixer,int recsrc)
@@ -215,6 +224,7 @@ static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsrif (mixer ==NULL )return -EIO ; +mutex_lock (&mixer->reg_mutex);if (mixer->get_recsrc && mixer->put_recsrc) {/* exclusive input */ if (recsrc & ~mixer->oss_recsrc) recsrc &= ~mixer->oss_recsrc;
@@ -240,6 +250,7 @@ static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsr } } } +mutex_unlock (&mixer->reg_mutex);return result; }
@@ -251,6 +262,7 @@ static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot)if (mixer ==NULL || slot >30 )return -EIO ; +mutex_lock (&mixer->reg_mutex); pslot = &mixer->slots[slot]; left = pslot->volume[0 ]; right = pslot->volume[1 ];
@@ -258,15 +270,21 @@ static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot) result = pslot->get_volume (fmixer, pslot, &left, &right);if (!pslot->stereo) right = left; -if (snd_BUG_ON (left <0 || left >100 )) -return -EIO ; -if (snd_BUG_ON (right <0 || right >100 )) -return -EIO ; +if (snd_BUG_ON (left <0 || left >100 )) { + result = -EIO ; + goto unlock; + } +if (snd_BUG_ON (right <0 || right >100 )) { + result = -EIO ; + goto unlock; + }if (result >=0 ) { pslot->volume[0 ] = left; pslot->volume[1 ] = right; result = (left &0xff ) | ((right &0xff ) <<8 ); } + unlock: +mutex_unlock (&mixer->reg_mutex);return result; }
@@ -279,6 +297,7 @@ static int snd_mixer_oss_set_volume(struct snd_mixer_oss_file *fmixer,if (mixer ==NULL || slot >30 )return -EIO ; +mutex_lock (&mixer->reg_mutex); pslot = &mixer->slots[slot];if (left >100 ) left =100 ;
@@ -289,10 +308,13 @@ static int snd_mixer_oss_set_volume(struct snd_mixer_oss_file *fmixer,if (pslot->put_volume) result = pslot->put_volume (fmixer, pslot, left, right);if (result <0 ) -return result; + goto unlock; pslot->volume[0 ] = left; pslot->volume[1 ] = right; -return (left &0xff ) | ((right &0xff ) <<8 ); + result = (left &0xff ) | ((right &0xff ) <<8 ); + unlock: +mutex_lock (&mixer->reg_mutex); +return result; }static int snd_mixer_oss_ioctl1 (struct snd_mixer_oss_file *fmixer,unsigned int cmd,unsigned long arg)