Merge "ALSA: timer: Fix race among timer ioctls" into LA.BF.1.1.3_rb1.15
This commit is contained in:
commit
4945378a30
|
@ -73,7 +73,7 @@ struct snd_timer_user {
|
|||
struct timespec tstamp; /* trigger tstamp */
|
||||
wait_queue_head_t qchange_sleep;
|
||||
struct fasync_struct *fasync;
|
||||
struct mutex tread_sem;
|
||||
struct mutex ioctl_lock;
|
||||
};
|
||||
|
||||
/* list of timers */
|
||||
|
@ -1266,7 +1266,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
|
|||
return -ENOMEM;
|
||||
spin_lock_init(&tu->qlock);
|
||||
init_waitqueue_head(&tu->qchange_sleep);
|
||||
mutex_init(&tu->tread_sem);
|
||||
mutex_init(&tu->ioctl_lock);
|
||||
tu->ticks = 1;
|
||||
tu->queue_size = 128;
|
||||
tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
|
||||
|
@ -1286,8 +1286,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
|
|||
if (file->private_data) {
|
||||
tu = file->private_data;
|
||||
file->private_data = NULL;
|
||||
mutex_lock(&tu->ioctl_lock);
|
||||
if (tu->timeri)
|
||||
snd_timer_close(tu->timeri);
|
||||
mutex_unlock(&tu->ioctl_lock);
|
||||
kfree(tu->queue);
|
||||
kfree(tu->tqueue);
|
||||
kfree(tu);
|
||||
|
@ -1525,7 +1527,6 @@ static int snd_timer_user_tselect(struct file *file,
|
|||
int err = 0;
|
||||
|
||||
tu = file->private_data;
|
||||
mutex_lock(&tu->tread_sem);
|
||||
if (tu->timeri) {
|
||||
snd_timer_close(tu->timeri);
|
||||
tu->timeri = NULL;
|
||||
|
@ -1569,7 +1570,6 @@ static int snd_timer_user_tselect(struct file *file,
|
|||
}
|
||||
|
||||
__err:
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1782,7 +1782,7 @@ enum {
|
|||
SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
|
||||
};
|
||||
|
||||
static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
||||
static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct snd_timer_user *tu;
|
||||
|
@ -1799,17 +1799,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
|||
{
|
||||
int xarg;
|
||||
|
||||
mutex_lock(&tu->tread_sem);
|
||||
if (tu->timeri) { /* too late */
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
if (tu->timeri) /* too late */
|
||||
return -EBUSY;
|
||||
}
|
||||
if (get_user(xarg, p)) {
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
if (get_user(xarg, p))
|
||||
return -EFAULT;
|
||||
}
|
||||
tu->tread = xarg ? 1 : 0;
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
return 0;
|
||||
}
|
||||
case SNDRV_TIMER_IOCTL_GINFO:
|
||||
|
@ -1842,6 +1836,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
|||
return -ENOTTY;
|
||||
}
|
||||
|
||||
static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct snd_timer_user *tu = file->private_data;
|
||||
long ret;
|
||||
|
||||
mutex_lock(&tu->ioctl_lock);
|
||||
ret = __snd_timer_user_ioctl(file, cmd, arg);
|
||||
mutex_unlock(&tu->ioctl_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int snd_timer_user_fasync(int fd, struct file * file, int on)
|
||||
{
|
||||
struct snd_timer_user *tu;
|
||||
|
|
Loading…
Reference in New Issue