Commit fdea53fe authored by Takashi Iwai's avatar Takashi Iwai

ALSA: timer: Limit max amount of slave instances

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.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b65f131b
...@@ -74,6 +74,9 @@ static LIST_HEAD(snd_timer_slave_list); ...@@ -74,6 +74,9 @@ static LIST_HEAD(snd_timer_slave_list);
/* lock for slave active lists */ /* lock for slave active lists */
static DEFINE_SPINLOCK(slave_active_lock); static DEFINE_SPINLOCK(slave_active_lock);
#define MAX_SLAVE_INSTANCES 1000
static int num_slaves;
static DEFINE_MUTEX(register_mutex); static DEFINE_MUTEX(register_mutex);
static int snd_timer_free(struct snd_timer *timer); static int snd_timer_free(struct snd_timer *timer);
...@@ -250,6 +253,10 @@ int snd_timer_open(struct snd_timer_instance **ti, ...@@ -250,6 +253,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
err = -EINVAL; err = -EINVAL;
goto unlock; goto unlock;
} }
if (num_slaves >= MAX_SLAVE_INSTANCES) {
err = -EBUSY;
goto unlock;
}
timeri = snd_timer_instance_new(owner, NULL); timeri = snd_timer_instance_new(owner, NULL);
if (!timeri) { if (!timeri) {
err = -ENOMEM; err = -ENOMEM;
...@@ -259,6 +266,7 @@ int snd_timer_open(struct snd_timer_instance **ti, ...@@ -259,6 +266,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
timeri->slave_id = tid->device; timeri->slave_id = tid->device;
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
list_add_tail(&timeri->open_list, &snd_timer_slave_list); list_add_tail(&timeri->open_list, &snd_timer_slave_list);
num_slaves++;
err = snd_timer_check_slave(timeri); err = snd_timer_check_slave(timeri);
if (err < 0) { if (err < 0) {
snd_timer_close_locked(timeri); snd_timer_close_locked(timeri);
...@@ -350,6 +358,8 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri) ...@@ -350,6 +358,8 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri)
} }
list_del(&timeri->open_list); list_del(&timeri->open_list);
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
num_slaves--;
/* force to stop the timer */ /* force to stop the timer */
snd_timer_stop(timeri); snd_timer_stop(timeri);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment