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

Commit dd9d894b authored by Takashi Iwai's avatar Takashi Iwai Committed by Greg Kroah-Hartman
Browse files

ALSA: timer: Use deferred fasync helper



[ Upstream commit 95cc637c1afd83fb7dd3d7c8a53710488f4caf9c ]

For avoiding the potential deadlock via kill_fasync() call, use the
new fasync helpers to defer the invocation from PCI API.  Note that
it's merely a workaround.

Reported-by: default avatar <syzbot+1ee0910eca9c94f71f25@syzkaller.appspotmail.com>
Reported-by: default avatar <syzbot+49b10793b867871ee26f@syzkaller.appspotmail.com>
Reported-by: default avatar <syzbot+8285e973a41b5aa68902@syzkaller.appspotmail.com>
Link: https://lore.kernel.org/r/20220728125945.29533-3-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 76f87b11
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ struct snd_timer_user {
	unsigned int filter;
	struct timespec tstamp;		/* trigger tstamp */
	wait_queue_head_t qchange_sleep;
	struct fasync_struct *fasync;
	struct snd_fasync *fasync;
	struct mutex ioctl_lock;
};

@@ -1317,7 +1317,7 @@ static void snd_timer_user_interrupt(struct snd_timer_instance *timeri,
	}
      __wake:
	spin_unlock(&tu->qlock);
	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
	snd_kill_fasync(tu->fasync, SIGIO, POLL_IN);
	wake_up(&tu->qchange_sleep);
}

@@ -1354,7 +1354,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
	spin_lock_irqsave(&tu->qlock, flags);
	snd_timer_user_append_to_tqueue(tu, &r1);
	spin_unlock_irqrestore(&tu->qlock, flags);
	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
	snd_kill_fasync(tu->fasync, SIGIO, POLL_IN);
	wake_up(&tu->qchange_sleep);
}

@@ -1421,7 +1421,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
	spin_unlock(&tu->qlock);
	if (append == 0)
		return;
	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
	snd_kill_fasync(tu->fasync, SIGIO, POLL_IN);
	wake_up(&tu->qchange_sleep);
}

@@ -1487,6 +1487,7 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
		if (tu->timeri)
			snd_timer_close(tu->timeri);
		mutex_unlock(&tu->ioctl_lock);
		snd_fasync_free(tu->fasync);
		kfree(tu->queue);
		kfree(tu->tqueue);
		kfree(tu);
@@ -2050,7 +2051,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on)
	struct snd_timer_user *tu;

	tu = file->private_data;
	return fasync_helper(fd, file, on, &tu->fasync);
	return snd_fasync_helper(fd, file, on, &tu->fasync);
}

static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,