ALSA: timer: Limit max amount of slave instances
diff mbox series

Message ID 20191106154257.5853-1-tiwai@suse.de
State New
Headers show
Series
  • ALSA: timer: Limit max amount of slave instances
Related show

Commit Message

Takashi Iwai Nov. 6, 2019, 3:42 p.m. UTC
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.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/timer.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Patch
diff mbox series

diff --git a/sound/core/timer.c b/sound/core/timer.c
index 5c9fbf3f4340..219249627cc3 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -74,6 +74,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);
@@ -250,6 +253,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;
@@ -259,6 +266,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);
@@ -350,6 +358,8 @@  static int snd_timer_close_locked(struct snd_timer_instance *timeri)
 	}
 
 	list_del(&timeri->open_list);
+	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+		num_slaves--;
 
 	/* force to stop the timer */
 	snd_timer_stop(timeri);