Re: sound: spinlock lockup in snd_timer_user_tinterrupt

From: Dmitry Vyukov
Date: Tue Feb 28 2017 - 09:09:43 EST


On Tue, Feb 28, 2017 at 2:58 PM, Takashi Iwai <tiwai@xxxxxxx> wrote:
> On Mon, 27 Feb 2017 21:46:48 +0100,
> Dmitry Vyukov wrote:
>>
>> Hello,
>>
>> The following program locks up system:
>> https://gist.githubusercontent.com/dvyukov/1b5cdca7f0fc6254afd4816901160e4c/raw/024c53be2112c83e5d64f3e4d5e8aa38ded727e3/gistfile1.txt
>
> Thanks. It doesn't look like the hard lockup, but it keeps the IRQs
> too busy, resulting in a quasi-lockup.
>
> The problem is that the timer accepted the too low resolution. A
> simple fix would be to give an error for a too short parameter.
> The fix patch is attached below. Please give it a try.

Pushed to our bots. Thanks.

> -- 8< --
> From: Takashi Iwai <tiwai@xxxxxxx>
> Subject: [PATCH] ALSA: timer: Reject user params with too small ticks
>
> When a user sets a too small ticks with a fine-grained timer like
> hrtimer, the kernel tries to fire up the timer irq too frequently.
> This may lead to the condensed locks, eventually the kernel spinlock
> lockup with warnings.
>
> For avoiding such a situation, we define a lower limit of the
> resolution, namely 1ms. When the user passes a too small tick value
> that results in less than that, the kernel returns -EINVAL now.
>
> Reported-by: Dmitry Vyukov <dvyukov@xxxxxxxxxx>
> Cc: <stable@xxxxxxxxxxxxxxx>
> Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
> ---
> sound/core/timer.c | 18 +++++++++++++++---
> 1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/sound/core/timer.c b/sound/core/timer.c
> index fc144f43faa6..ad153149b231 100644
> --- a/sound/core/timer.c
> +++ b/sound/core/timer.c
> @@ -1702,9 +1702,21 @@ static int snd_timer_user_params(struct file *file,
> return -EBADFD;
> if (copy_from_user(&params, _params, sizeof(params)))
> return -EFAULT;
> - if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
> - err = -EINVAL;
> - goto _end;
> + if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
> + u64 resolution;
> +
> + if (params.ticks < 1) {
> + err = -EINVAL;
> + goto _end;
> + }
> +
> + /* Don't allow resolution less than 1ms */
> + resolution = snd_timer_resolution(tu->timeri);
> + resolution *= params.ticks;
> + if (resolution < 1000000) {
> + err = -EINVAL;
> + goto _end;
> + }
> }
> if (params.queue_size > 0 &&
> (params.queue_size < 32 || params.queue_size > 1024)) {
> --
> 2.11.1
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller+unsubscribe@xxxxxxxxxxxxxxxxx
> For more options, visit https://groups.google.com/d/optout.