Unverified Commit 2ce0a396 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!5724 ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs

parents d9f066e0 1e11cb0a
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ static void run_spu_dma(struct work_struct *work)
		dreamcastcard->clicks++;
		if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER))
			dreamcastcard->clicks %= AICA_PERIOD_NUMBER;
		if (snd_pcm_running(dreamcastcard->substream))
			mod_timer(&dreamcastcard->timer, jiffies + 1);
	}
}
@@ -291,6 +292,8 @@ static void aica_period_elapsed(struct timer_list *t)
	/*timer function - so cannot sleep */
	int play_period;
	struct snd_pcm_runtime *runtime;
	if (!snd_pcm_running(substream))
		return;
	runtime = substream->runtime;
	dreamcastcard = substream->pcm->private_data;
	/* Have we played out an additional period? */
@@ -351,12 +354,19 @@ static int snd_aicapcm_pcm_open(struct snd_pcm_substream
	return 0;
}

static int snd_aicapcm_pcm_sync_stop(struct snd_pcm_substream *substream)
{
	struct snd_card_aica *dreamcastcard = substream->pcm->private_data;

	del_timer_sync(&dreamcastcard->timer);
	cancel_work_sync(&dreamcastcard->spu_dma_work);
	return 0;
}

static int snd_aicapcm_pcm_close(struct snd_pcm_substream
				 *substream)
{
	struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
	flush_work(&(dreamcastcard->spu_dma_work));
	del_timer(&dreamcastcard->timer);
	dreamcastcard->substream = NULL;
	kfree(dreamcastcard->channel);
	spu_disable();
@@ -402,6 +412,7 @@ static const struct snd_pcm_ops snd_aicapcm_playback_ops = {
	.prepare = snd_aicapcm_pcm_prepare,
	.trigger = snd_aicapcm_pcm_trigger,
	.pointer = snd_aicapcm_pcm_pointer,
	.sync_stop = snd_aicapcm_pcm_sync_stop,
};

/* TO DO: set up to handle more than one pcm instance */