Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71603dc9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ALSA: timer: Fix race among timer ioctls"

parents 98a36d37 8cf82bb0
Loading
Loading
Loading
Loading
+19 −13
Original line number Diff line number Diff line
@@ -74,7 +74,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 */
@@ -1335,7 +1335,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),
@@ -1355,8 +1355,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);
@@ -1594,7 +1596,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;
@@ -1638,7 +1639,6 @@ static int snd_timer_user_tselect(struct file *file,
	}

      __err:
      	mutex_unlock(&tu->tread_sem);
	return err;
}

@@ -1852,7 +1852,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;
@@ -1869,17 +1869,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:
@@ -1912,6 +1906,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;