mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	pcm: direct plugins - fix bad memory access when channel bindings do not match hw
Fix and cleanup snd_pcm_direct_check_interleave() function. Add requested / hardware channel check and use goto when the interleaved Fixes: https://github.com/alsa-project/alsa-lib/issues/117 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
		
							parent
							
								
									a5e11f9a81
								
							
						
					
					
						commit
						e0e0846590
					
				
					 1 changed files with 17 additions and 23 deletions
				
			
		| 
						 | 
					@ -1627,43 +1627,37 @@ int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix)
 | 
				
			||||||
int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm)
 | 
					int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int chn, channels;
 | 
						unsigned int chn, channels;
 | 
				
			||||||
	int bits, interleaved = 1;
 | 
						int bits;
 | 
				
			||||||
	const snd_pcm_channel_area_t *dst_areas;
 | 
						const snd_pcm_channel_area_t *dst_areas;
 | 
				
			||||||
	const snd_pcm_channel_area_t *src_areas;
 | 
						const snd_pcm_channel_area_t *src_areas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bits = snd_pcm_format_physical_width(pcm->format);
 | 
						bits = snd_pcm_format_physical_width(pcm->format);
 | 
				
			||||||
	if ((bits % 8) != 0)
 | 
						if ((bits % 8) != 0)
 | 
				
			||||||
		interleaved = 0;
 | 
							goto __nointerleaved;
 | 
				
			||||||
	channels = dmix->channels;
 | 
						channels = dmix->channels;
 | 
				
			||||||
 | 
						if (channels != dmix->spcm->channels)
 | 
				
			||||||
 | 
							goto __nointerleaved;
 | 
				
			||||||
	dst_areas = snd_pcm_mmap_areas(dmix->spcm);
 | 
						dst_areas = snd_pcm_mmap_areas(dmix->spcm);
 | 
				
			||||||
	src_areas = snd_pcm_mmap_areas(pcm);
 | 
						src_areas = snd_pcm_mmap_areas(pcm);
 | 
				
			||||||
	for (chn = 1; chn < channels; chn++) {
 | 
						for (chn = 1; chn < channels; chn++) {
 | 
				
			||||||
		if (dst_areas[chn-1].addr != dst_areas[chn].addr) {
 | 
							if (dst_areas[chn-1].addr != dst_areas[chn].addr)
 | 
				
			||||||
			interleaved = 0;
 | 
								goto __nointerleaved;
 | 
				
			||||||
			break;
 | 
							if (src_areas[chn-1].addr != src_areas[chn].addr)
 | 
				
			||||||
		}
 | 
								goto __nointerleaved;
 | 
				
			||||||
		if (src_areas[chn-1].addr != src_areas[chn].addr) {
 | 
					 | 
				
			||||||
			interleaved = 0;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (chn = 0; chn < channels; chn++) {
 | 
						for (chn = 0; chn < channels; chn++) {
 | 
				
			||||||
		if (dmix->bindings && dmix->bindings[chn] != chn) {
 | 
							if (dmix->bindings && dmix->bindings[chn] != chn)
 | 
				
			||||||
			interleaved = 0;
 | 
								goto __nointerleaved;
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (dst_areas[chn].first != chn * bits ||
 | 
							if (dst_areas[chn].first != chn * bits ||
 | 
				
			||||||
		    dst_areas[chn].step != channels * bits) {
 | 
							    dst_areas[chn].step != channels * bits)
 | 
				
			||||||
			interleaved = 0;
 | 
								goto __nointerleaved;
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (src_areas[chn].first != chn * bits ||
 | 
							if (src_areas[chn].first != chn * bits ||
 | 
				
			||||||
		    src_areas[chn].step != channels * bits) {
 | 
							    src_areas[chn].step != channels * bits)
 | 
				
			||||||
			interleaved = 0;
 | 
								goto __nointerleaved;
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
						return dmix->interleaved = 1;
 | 
				
			||||||
	return dmix->interleaved = interleaved;
 | 
					__nointerleaved:
 | 
				
			||||||
 | 
						return dmix->interleaved = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue