Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 691960ea authored by Takashi Iwai's avatar Takashi Iwai Committed by Greg Kroah-Hartman
Browse files

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: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent b90fd098
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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);