Commit 96b09709 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: pcm: Use deferred fasync helper



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

Reported-by: default avatar <syzbot+8285e973a41b5aa68902@syzkaller.appspotmail.com>
Reported-by: default avatar <syzbot+669c9abf11a6a011dd09@syzkaller.appspotmail.com>
Link: https://lore.kernel.org/r/20220728125945.29533-4-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 95cc637c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -399,7 +399,7 @@ struct snd_pcm_runtime {
	snd_pcm_uframes_t twake; 	/* do transfer (!poll) wakeup if non-zero */
	wait_queue_head_t sleep;	/* poll sleep */
	wait_queue_head_t tsleep;	/* transfer sleep */
	struct fasync_struct *fasync;
	struct snd_fasync *fasync;
	bool stop_operating;		/* sync_stop will be called */
	struct mutex buffer_mutex;	/* protect for buffer changes */
	atomic_t buffer_accessing;	/* >0: in r/w operation, <0: blocked */
+1 −0
Original line number Diff line number Diff line
@@ -1007,6 +1007,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
		substream->runtime = NULL;
	}
	mutex_destroy(&runtime->buffer_mutex);
	snd_fasync_free(runtime->fasync);
	kfree(runtime);
	put_pid(substream->pid);
	substream->pid = NULL;
+1 −1
Original line number Diff line number Diff line
@@ -1822,7 +1822,7 @@ void snd_pcm_period_elapsed_under_stream_lock(struct snd_pcm_substream *substrea
		snd_timer_interrupt(substream->timer, 1);
#endif
 _end:
	kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
	snd_kill_fasync(runtime->fasync, SIGIO, POLL_IN);
}
EXPORT_SYMBOL(snd_pcm_period_elapsed_under_stream_lock);

+1 −1
Original line number Diff line number Diff line
@@ -3951,7 +3951,7 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
	runtime = substream->runtime;
	if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
		return -EBADFD;
	return fasync_helper(fd, file, on, &runtime->fasync);
	return snd_fasync_helper(fd, file, on, &runtime->fasync);
}

/*