]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
ALSA: timer: Limit max amount of slave instances
authorTakashi Iwai <tiwai@suse.de>
Wed, 6 Nov 2019 15:42:57 +0000 (16:42 +0100)
committerKhalid Elmously <khalid.elmously@canonical.com>
Wed, 29 Jan 2020 04:45:21 +0000 (23:45 -0500)
BugLink: https://bugs.launchpad.net/bugs/1859712
[ Upstream commit fdea53fe5de532969a332d6e5e727f2ad8bf084d ]

The fuzzer tries to open the timer instances as much as possible, and
this may cause a system hiccup easily.  We've already introduced the
cap for the max number of available instances for the h/w timers, and
we should put such a limit also to the slave timers, too.

This patch introduces the limit to the multiple opened slave timers.
The upper limit is hard-coded to 1000 for now, which should suffice
for any practical usages up to now.

Link: https://lore.kernel.org/r/20191106154257.5853-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
sound/core/timer.c

index ced8a4c9fb5a2a4bcd9d57e92a725ce52ebc54ea..92bc43fab5ce2ac725ffc692f15e9d737a054f04 100644 (file)
@@ -88,6 +88,9 @@ static LIST_HEAD(snd_timer_slave_list);
 /* lock for slave active lists */
 static DEFINE_SPINLOCK(slave_active_lock);
 
+#define MAX_SLAVE_INSTANCES    1000
+static int num_slaves;
+
 static DEFINE_MUTEX(register_mutex);
 
 static int snd_timer_free(struct snd_timer *timer);
@@ -266,6 +269,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
                        err = -EINVAL;
                        goto unlock;
                }
+               if (num_slaves >= MAX_SLAVE_INSTANCES) {
+                       err = -EBUSY;
+                       goto unlock;
+               }
                timeri = snd_timer_instance_new(owner, NULL);
                if (!timeri) {
                        err = -ENOMEM;
@@ -275,6 +282,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
                timeri->slave_id = tid->device;
                timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
                list_add_tail(&timeri->open_list, &snd_timer_slave_list);
+               num_slaves++;
                err = snd_timer_check_slave(timeri);
                if (err < 0) {
                        snd_timer_close_locked(timeri, &card_dev_to_put);
@@ -364,6 +372,8 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri,
        struct snd_timer_instance *slave, *tmp;
 
        list_del(&timeri->open_list);
+       if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+               num_slaves--;
 
        /* force to stop the timer */
        snd_timer_stop(timeri);