FAILED: patch "[PATCH] ALSA: timer: Fix race between read and ioctl" failed to apply to 3.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 3.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
d11662f4f798b50d8c8743f433842c3e40fe3378Mon Sep 17 00:00:00 2001
From: Takashi Iwai <[email protected]>
Date: Fri, 2 Jun 2017 15:03:38 +0200
Subject: [PATCH] ALSA: timer: Fix race between read and ioctl
The read from ALSA timer device, the function snd_timer_user_tread(), may access to an uninitialized struct snd_timer_user fields when the read is concurrently performed while the ioctl like snd_timer_user_tselect() is invoked. We have already fixed the races among ioctls via a mutex, but we seem to have forgotten the race between read vs ioctl.
This patch simply applies (more exactly extends the already applied range of) tu->ioctl_lock in snd_timer_user_tread() for closing the race window.
sound/core/timer.c +4 -2
@@ -1959,6 +1959,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, tu = file->private_data; unit = tu->tread ?sizeof (struct snd_timer_tread ) :sizeof (struct snd_timer_read ); +mutex_lock (&tu->ioctl_lock);spin_lock_irq (&tu->qlock);while ((long )count - result >= unit) {while (!tu->qused) {
@@ -1974,7 +1975,9 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,add_wait_queue (&tu->qchange_sleep, &wait);spin_unlock_irq (&tu->qlock); +mutex_unlock (&tu->ioctl_lock);schedule (); +mutex_lock (&tu->ioctl_lock);spin_lock_irq (&tu->qlock);remove_wait_queue (&tu->qchange_sleep, &wait);
@@ -1994,7 +1997,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, tu->qused--;spin_unlock_irq (&tu->qlock); -mutex_lock (&tu->ioctl_lock);if (tu->tread) {if (copy_to_user (buffer, &tu->tqueue[qhead],sizeof (struct snd_timer_tread )))
@@ -2004,7 +2006,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, sizeof(struct snd_timer_read))) err = -EFAULT ; } -mutex_unlock (&tu->ioctl_lock);spin_lock_irq (&tu->qlock);if (err <0 )
@@ -2014,6 +2015,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, } _error:spin_unlock_irq (&tu->qlock); +mutex_unlock (&tu->ioctl_lock);return result >0 ? result : err; }