On Thu, 11 Apr 2002, Sander van Leeuwen wrote:
> Hi,
>
> I'm currently porting ALSA to OS/2 and have encountered a bug in
> snd_pcm_playback_silence (core\pcm_lib.c)
> While playing an 8 bits stereo 44.1khz wave file the system
> would trap when stopping the stream. The cause was heap
> corruption caused by this function. There is no check to
> see if the offset + amount of frames to silence is larger
> than the buffer size.
> The patch below fixes this.
>
> Sander
>
>
>
> --- E:\Development\ALSA.Linux\alsa-kernel\core\pcm_lib.c Wed Apr 10 21:55:18
>2002
> +++ E:\Development\ALSA.OS2\GPL\alsa\core\pcm_lib.c Thu Apr 11 17:01:38 2002
> @@ -60,6 +56,12 @@
> ofs = runtime->silenced_start % runtime->buffer_size + runtime->silenced_size;
> if (ofs >= runtime->buffer_size)
> ofs -= runtime->buffer_size;
> +#ifdef TARGET_OS2
> + if (ofs + frames > runtime->buffer_size) {
> + frames = runtime->buffer_size - ofs;
> + }
> +#endif
> if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
> runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
> if (substream->ops->silence) {
Above patch is not perfect, but thank you for pointing to this problem.
I've applied this fix to CVS:
Index: pcm_lib.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/pcm_lib.c,v
retrieving revision 1.9
diff -u -r1.9 pcm_lib.c
--- pcm_lib.c 9 Apr 2002 06:53:35 -0000 1.9
+++ pcm_lib.c 12 Apr 2002 07:04:47 -0000
@@ -34,7 +34,7 @@
void snd_pcm_playback_silence(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_pcm_uframes_t frames, ofs;
+ snd_pcm_uframes_t frames, ofs, transfer;
snd_pcm_sframes_t noise_dist;
if (runtime->silenced_start != runtime->control->appl_ptr) {
snd_pcm_sframes_t n = runtime->control->appl_ptr -
runtime->silenced_start;
@@ -60,32 +60,36 @@
ofs = runtime->silenced_start % runtime->buffer_size + runtime->silenced_size;
if (ofs >= runtime->buffer_size)
ofs -= runtime->buffer_size;
- if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
- runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
- if (substream->ops->silence) {
- int err;
- err = substream->ops->silence(substream, -1, ofs, frames);
- snd_assert(err >= 0, );
- } else {
- char *hwbuf = runtime->dma_area + frames_to_bytes(runtime,
ofs);
- snd_pcm_format_set_silence(runtime->format, hwbuf, frames *
runtime->channels);
- }
- } else {
- unsigned int c;
- unsigned int channels = runtime->channels;
- if (substream->ops->silence) {
- for (c = 0; c < channels; ++c) {
+ while (frames > 0) {
+ transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size
+- ofs : frames;
+ if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
+ runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
+ if (substream->ops->silence) {
int err;
- err = substream->ops->silence(substream, c, ofs,
frames);
+ err = substream->ops->silence(substream, -1, ofs,
+transfer);
snd_assert(err >= 0, );
+ } else {
+ char *hwbuf = runtime->dma_area +
+frames_to_bytes(runtime, ofs);
+ snd_pcm_format_set_silence(runtime->format, hwbuf,
+transfer * runtime->channels);
}
} else {
- size_t dma_csize = runtime->dma_bytes / channels;
- for (c = 0; c < channels; ++c) {
- char *hwbuf = runtime->dma_area + (c * dma_csize) +
samples_to_bytes(runtime, ofs);
- snd_pcm_format_set_silence(runtime->format, hwbuf,
frames);
+ unsigned int c;
+ unsigned int channels = runtime->channels;
+ if (substream->ops->silence) {
+ for (c = 0; c < channels; ++c) {
+ int err;
+ err = substream->ops->silence(substream, c,
+ofs, transfer);
+ snd_assert(err >= 0, );
+ }
+ } else {
+ size_t dma_csize = runtime->dma_bytes / channels;
+ for (c = 0; c < channels; ++c) {
+ char *hwbuf = runtime->dma_area + (c *
+dma_csize) + samples_to_bytes(runtime, ofs);
+ snd_pcm_format_set_silence(runtime->format,
+hwbuf, transfer);
+ }
}
}
+ frames -= transfer;
}
runtime->silenced_size += frames;
}
Jaroslav
-----
Jaroslav Kysela <[EMAIL PROTECTED]>
Linux Kernel Sound Maintainer
ALSA Project http://www.alsa-project.org
SuSE Linux http://www.suse.com
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel