From 356f78ee8101e6d567716698b9c2833b5a49d389 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 24 May 2023 03:16:54 +0300 Subject: [PATCH] engine: platform: sdl: fix possible buffer overrun in SDL port audio code --- engine/platform/sdl/s_sdl.c | 42 ++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/engine/platform/sdl/s_sdl.c b/engine/platform/sdl/s_sdl.c index 10998486..0cde9bc5 100644 --- a/engine/platform/sdl/s_sdl.c +++ b/engine/platform/sdl/s_sdl.c @@ -49,20 +49,26 @@ static SDL_AudioDeviceID in_dev = 0; static SDL_AudioFormat sdl_format; static char sdl_backend_name[32]; -//static qboolean snd_firsttime = true; -//static qboolean primary_format_set; - void SDL_SoundCallback( void *userdata, Uint8 *stream, int len ) { - int size = dma.samples << 1; - int pos = dma.samplepos << 1; - int wrapped = pos + len - size; + const int size = dma.samples << 1; + int pos; + int wrapped; #if ! SDL_VERSION_ATLEAST( 2, 0, 0 ) if( !dma.buffer ) + { + memset( stream, 0, len ); return; + } #endif + pos = dma.samplepos << 1; + if( pos >= size ) + pos = dma.samplepos = 0; + + wrapped = pos + len - size; + if( wrapped < 0 ) { memcpy( stream, dma.buffer + pos, len ); @@ -71,10 +77,14 @@ void SDL_SoundCallback( void *userdata, Uint8 *stream, int len ) else { int remaining = size - pos; + memcpy( stream, dma.buffer + pos, remaining ); memcpy( stream + remaining, dma.buffer, wrapped ); dma.samplepos = wrapped >> 1; } + + if( dma.samplepos >= size ) + dma.samplepos = 0; } /* @@ -90,19 +100,17 @@ qboolean SNDDMA_Init( void ) SDL_AudioSpec desired, obtained; int samplecount; - if( SDL_Init( SDL_INIT_AUDIO ) ) + // even if we don't have PA + // we still can safely set env variables + SDL_setenv( "PULSE_PROP_application.name", GI->title, 1 ); + SDL_setenv( "PULSE_PROP_media.role", "game", 1 ); + + if( SDL_Init( SDL_INIT_AUDIO )) { - Con_Reportf( S_ERROR "Audio: SDL: %s \n", SDL_GetError( ) ); + Con_Reportf( S_ERROR "Audio: SDL: %s \n", SDL_GetError( ) ); return false; } - // even if we don't have PA - // we still can safely set env variables -#if XASH_POSIX - setenv( "PULSE_PROP_application.name", GI->title, 1 ); - setenv( "PULSE_PROP_media.role", "game", 1 ); -#endif // XASH_POSIX - memset( &desired, 0, sizeof( desired ) ); desired.freq = SOUND_DMA_SPEED; desired.format = AUDIO_S16LSB; @@ -166,7 +174,7 @@ Makes sure dma.buffer is valid */ void SNDDMA_BeginPainting( void ) { -// SDL_LockAudioDevice( sdl_dev ); + SDL_LockAudioDevice( sdl_dev ); } /* @@ -179,7 +187,7 @@ Also unlocks the dsound buffer */ void SNDDMA_Submit( void ) { -// SDL_UnlockAudioDevice( sdl_dev ); + SDL_UnlockAudioDevice( sdl_dev ); } /*