summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-11-06 16:42:57 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-12-31 12:37:23 +0100
commit62c94beda69786d7e988f99e2dbabd1be96d5bd7 (patch)
treed2bdb4c372289a39b6a04d6ed50301eff7c146a0
parent6021cd87982255b7c7518e69cec1c78241e5d36d (diff)
ALSA: timer: Limit max amount of slave instances
[ 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>
-rw-r--r--sound/core/timer.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index c60dfd52e8a6..22589a073423 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -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);