8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 16:43:03 +01:00

Catch possible stack overflow when preparing and compiling user statements

This commit is contained in:
Vlad Khorsun 2024-09-20 17:30:32 +03:00
parent c75b160dc0
commit 6b445c0dc5

View File

@ -43,6 +43,7 @@
#include "../common/intlobj_new.h"
#include "../jrd/jrd.h"
#include "../jrd/status.h"
#include "../jrd/ibsetjmp.h"
#include "../common/CharSet.h"
#include "../dsql/Parser.h"
#include "../dsql/ddl_proto.h"
@ -85,6 +86,7 @@ using namespace Firebird;
static ULONG get_request_info(thread_db*, DsqlRequest*, ULONG, UCHAR*);
static dsql_dbb* init(Jrd::thread_db*, Jrd::Attachment*);
static DsqlRequest* prepareRequest(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, unsigned, bool);
static DsqlRequest* safePrepareRequest(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, bool);
static RefPtr<DsqlStatement> prepareStatement(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT,
unsigned, bool, ntrace_result_t* traceResult);
static UCHAR* put_item(UCHAR, const USHORT, const UCHAR*, UCHAR*, const UCHAR* const);
@ -260,7 +262,7 @@ DsqlRequest* DSQL_prepare(thread_db* tdbb,
{
// Allocate a new request block and then prepare the request.
dsqlRequest = prepareRequest(tdbb, database, transaction, length, string, dialect,
dsqlRequest = safePrepareRequest(tdbb, database, transaction, length, string, dialect,
prepareFlags, isInternalRequest);
// Can not prepare a CREATE DATABASE/SCHEMA statement
@ -335,7 +337,7 @@ void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tr
try
{
dsqlRequest = prepareRequest(tdbb, database, *tra_handle, length, string, dialect,
dsqlRequest = safePrepareRequest(tdbb, database, *tra_handle, length, string, dialect,
0, isInternalRequest);
const auto dsqlStatement = dsqlRequest->getDsqlStatement();
@ -439,6 +441,23 @@ static dsql_dbb* init(thread_db* tdbb, Jrd::Attachment* attachment)
return attachment->att_dsql_instance;
}
// Use SEH frame when preparing user requests to catch possible stack overflows
static DsqlRequest* safePrepareRequest(thread_db* tdbb, dsql_dbb* database, jrd_tra* transaction,
ULONG textLength, const TEXT* text, USHORT clientDialect, bool isInternalRequest)
{
if (isInternalRequest)
return prepareRequest(tdbb, database, transaction, textLength, text, clientDialect, true);
#ifdef WIN_NT
START_CHECK_FOR_EXCEPTIONS(NULL);
#endif
return prepareRequest(tdbb, database, transaction, textLength, text, clientDialect, false);
#ifdef WIN_NT
END_CHECK_FOR_EXCEPTIONS(NULL);
#endif
}
// Prepare a request for execution.
// Note: caller is responsible for pool handling.