| From 36fa4a82a73983fa0106e7306adb5ab5bc02c166 Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Wed, 6 Nov 2019 16:42:57 +0100 |
| Subject: [PATCH] ALSA: timer: Limit max amount of slave instances |
| |
| commit fdea53fe5de532969a332d6e5e727f2ad8bf084d upstream. |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/sound/core/timer.c b/sound/core/timer.c |
| index 59ae21b0bb93..013f0e69ff0f 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); |
| @@ -252,6 +255,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; |
| @@ -261,6 +268,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); |
| @@ -356,6 +364,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); |
| -- |
| 2.7.4 |
| |