From e03753c46cb404e27888868d3cb9a1db57f1bf6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 14 Mar 2023 23:33:10 +0100 Subject: [PATCH 1/6] Pa_Initalze(): Guard against recursive calls. This fixes a stack overflow when a diver uses portaudio as well like FlexAsio --- src/common/pa_front.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/common/pa_front.c b/src/common/pa_front.c index 89b4335b8..814a24d3f 100644 --- a/src/common/pa_front.c +++ b/src/common/pa_front.c @@ -67,6 +67,7 @@ #include #include /* needed for strtol() */ #include /* needed by PA_VALIDATE_ENDIANNESS */ +#include #include "portaudio.h" #include "pa_util.h" @@ -154,6 +155,7 @@ static PaUtilHostApiRepresentation **hostApis_ = 0; static int hostApisCount_ = 0; static int defaultHostApiIndex_ = 0; static int initializationCount_ = 0; +static bool initializing_ = false; static int deviceCount_ = 0; PaUtilStreamRepresentation *firstOpenStream_ = NULL; @@ -360,8 +362,19 @@ PaError Pa_Initialize( void ) ++initializationCount_; result = paNoError; } + else if( initializing_ ) + { + // a concurrent initialization is already running + result = paInternalError; + } else { + // set initializing_ here to + // let recursive calls execute the if branch above. + // This can happen if a driver like FlexAsio itself uses portaudio + // and avoids a stack overflow in the user application. + initializing_ = true; + PA_VALIDATE_TYPE_SIZES; PA_VALIDATE_ENDIANNESS; @@ -371,6 +384,8 @@ PaError Pa_Initialize( void ) result = InitializeHostApis(); if( result == paNoError ) ++initializationCount_; + + initializing_ = false; } PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result ); From a89765094669c512060b998446484e363919459a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 15 Mar 2023 14:58:37 +0100 Subject: [PATCH 2/6] Add a debug statement when re-enter Pa_Initalize() --- src/common/pa_front.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/pa_front.c b/src/common/pa_front.c index 814a24d3f..7573f1449 100644 --- a/src/common/pa_front.c +++ b/src/common/pa_front.c @@ -365,6 +365,7 @@ PaError Pa_Initialize( void ) else if( initializing_ ) { // a concurrent initialization is already running + PA_DEBUG(("Attempting to re-enter Pa_Initialize(), aborting!\n")); result = paInternalError; } else From 079943ed13da7639dba8fc5fc529c3a872e9ccde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 15 Mar 2023 15:00:07 +0100 Subject: [PATCH 3/6] Add link to issue fixed by the previous commits --- src/common/pa_front.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/pa_front.c b/src/common/pa_front.c index 7573f1449..a8798f082 100644 --- a/src/common/pa_front.c +++ b/src/common/pa_front.c @@ -374,6 +374,7 @@ PaError Pa_Initialize( void ) // let recursive calls execute the if branch above. // This can happen if a driver like FlexAsio itself uses portaudio // and avoids a stack overflow in the user application. + // https://github.com/PortAudio/portaudio/issues/766 initializing_ = true; PA_VALIDATE_TYPE_SIZES; From 9885ecca56c32454abd3aae542823946914f70dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 16 Mar 2023 00:06:14 +0100 Subject: [PATCH 4/6] Don't use C99 stdbool.h --- src/common/pa_front.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/common/pa_front.c b/src/common/pa_front.c index a8798f082..996eb08ad 100644 --- a/src/common/pa_front.c +++ b/src/common/pa_front.c @@ -67,7 +67,6 @@ #include #include /* needed for strtol() */ #include /* needed by PA_VALIDATE_ENDIANNESS */ -#include #include "portaudio.h" #include "pa_util.h" @@ -155,7 +154,7 @@ static PaUtilHostApiRepresentation **hostApis_ = 0; static int hostApisCount_ = 0; static int defaultHostApiIndex_ = 0; static int initializationCount_ = 0; -static bool initializing_ = false; +static int initializing_ = 0; static int deviceCount_ = 0; PaUtilStreamRepresentation *firstOpenStream_ = NULL; @@ -375,7 +374,7 @@ PaError Pa_Initialize( void ) // This can happen if a driver like FlexAsio itself uses portaudio // and avoids a stack overflow in the user application. // https://github.com/PortAudio/portaudio/issues/766 - initializing_ = true; + initializing_ = 1; PA_VALIDATE_TYPE_SIZES; PA_VALIDATE_ENDIANNESS; @@ -387,7 +386,7 @@ PaError Pa_Initialize( void ) if( result == paNoError ) ++initializationCount_; - initializing_ = false; + initializing_ = 0; } PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result ); From 9995043dea2a1712cb58b9a2b474d681d497a1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 28 Mar 2023 08:24:17 +0200 Subject: [PATCH 5/6] Use new error code paCanNotInitializeRecursively --- include/portaudio.h | 3 ++- src/common/pa_front.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/portaudio.h b/include/portaudio.h index 8a8250fa2..9eaeeaedb 100644 --- a/include/portaudio.h +++ b/include/portaudio.h @@ -151,7 +151,8 @@ typedef enum PaErrorCode paCanNotReadFromAnOutputOnlyStream, paCanNotWriteToAnInputOnlyStream, paIncompatibleStreamHostApi, - paBadBufferPtr + paBadBufferPtr, + paCanNotInitializeRecursively } PaErrorCode; diff --git a/src/common/pa_front.c b/src/common/pa_front.c index 996eb08ad..eab385b70 100644 --- a/src/common/pa_front.c +++ b/src/common/pa_front.c @@ -365,7 +365,7 @@ PaError Pa_Initialize( void ) { // a concurrent initialization is already running PA_DEBUG(("Attempting to re-enter Pa_Initialize(), aborting!\n")); - result = paInternalError; + result = paCanNotInitializeRecursively; } else { @@ -469,6 +469,7 @@ const char *Pa_GetErrorText( PaError errorCode ) case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break; case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break; case paBadBufferPtr: result = "Bad buffer pointer"; break; + case paCanNotInitializeRecursively: result = "PortAudio can not initialized recursively"; break; default: if( errorCode > 0 ) result = "Invalid error code (value greater than zero)"; From 8faf0f61c9a79baafbd4806e0c6c6621bafb34f4 Mon Sep 17 00:00:00 2001 From: Ross Bencina Date: Sat, 1 Apr 2023 10:17:13 +1100 Subject: [PATCH 6/6] Fix error text for paCanNotInitializeRecursively --- src/common/pa_front.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/pa_front.c b/src/common/pa_front.c index eab385b70..9f81f2673 100644 --- a/src/common/pa_front.c +++ b/src/common/pa_front.c @@ -469,7 +469,7 @@ const char *Pa_GetErrorText( PaError errorCode ) case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break; case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break; case paBadBufferPtr: result = "Bad buffer pointer"; break; - case paCanNotInitializeRecursively: result = "PortAudio can not initialized recursively"; break; + case paCanNotInitializeRecursively: result = "PortAudio can not be initialized recursively"; break; default: if( errorCode > 0 ) result = "Invalid error code (value greater than zero)";