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

Vulnerability reported by Daniel Urban.

First step: reorganize code.
Please do a full rebuild after retrieving those changes.
This commit is contained in:
robocop 2004-09-22 01:59:39 +00:00
parent 921f83b8b7
commit e6cb17cac6
18 changed files with 151 additions and 101 deletions

View File

@ -72,7 +72,6 @@ global:
gds__get_segment;
gds__get_slice;
gds__interprete;
gds_interprete_cpp;
gds__log;
gds__log_status;
gds__map_blobs;
@ -246,7 +245,7 @@ global:
# Error-handling functions
isc_interprete;
isc_interprete_cpp;
fb_interpret;
isc_print_sqlerror;
isc_print_status;
isc_sqlcode;

View File

@ -63,7 +63,6 @@ EXPORTS
gds__get_segment @39
gds__get_slice @40
gds__interprete @41
gds_interprete_cpp
gds__log @42
gds__log_status @142
gds__map_blobs @240
@ -237,7 +236,7 @@ EXPORTS
; Error-handling functions
isc_interprete @141
isc_interprete_cpp
fb_interpret
isc_print_sqlerror @150
isc_print_status @151
isc_sqlcode @165

View File

@ -57,7 +57,6 @@ EXPORTS
gds__get_segment=fbclient.gds__get_segment @39
gds__get_slice=fbclient.gds__get_slice @40
gds__interprete=fbclient.gds__interprete @41
gds_interprete_cpp=fbclient.gds_interprete_cpp
gds__log=fbclient.gds__log @42
gds__msg_format=fbclient.gds__msg_format @43
gds__msg_lookup=fbclient.gds__msg_lookup @44
@ -149,7 +148,7 @@ EXPORTS
isc_get_segment=fbclient.isc_get_segment @139
isc_get_slice=fbclient.isc_get_slice @140
isc_interprete=fbclient.isc_interprete @141
isc_interprete_cpp=fbclient.isc_interprete_cpp
fb_interpret=fbclient.fb_interpret
gds__log_status=fbclient.gds__log_status @142
isc_open=fbclient.isc_open @143
isc_open_blob=fbclient.isc_open_blob @144

View File

@ -67,7 +67,7 @@ EXPORTS
_gds__ftof @13
_gds__interprete @14
_gds__interprete_a @15
_gds_interprete_cpp
_fb_interpret
_gds__log @16
_gds__log_status @17
_gds__msg_close @18

View File

@ -24,7 +24,7 @@
//
//____________________________________________________________
//
// $Id: alice.cpp,v 1.71 2004-09-01 14:51:33 alexpeshkoff Exp $
// $Id: alice.cpp,v 1.72 2004-09-22 01:58:52 robocop Exp $
//
// 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
// conditionals, as the engine now fully supports
@ -673,7 +673,7 @@ void ALICE_print(USHORT number,
//____________________________________________________________
//
// Print error message. Use isc_interprete_cpp
// Print error message. Use fb_interpret
// to allow redirecting output.
//
@ -683,29 +683,31 @@ void ALICE_print_status(const ISC_STATUS* status_vector)
{
const ISC_STATUS* vector = status_vector;
#ifdef SUPERSERVER
int i = 0, j;
int i = 0;
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
ISC_STATUS* status = tdgbl->service_blk->svc_status;
if (status != status_vector) {
while (*status && (++i < ISC_STATUS_LENGTH)) {
status++;
}
for (j = 0; status_vector[j] && (i < ISC_STATUS_LENGTH); j++, i++) {
for (int j = 0; status_vector[j] && (i < ISC_STATUS_LENGTH); j++, i++) {
*status++ = status_vector[j];
}
}
#endif
SCHAR s[1024];
isc_interprete_cpp(s, &vector);
translate_cp(s);
alice_output("%s\n", s);
// Continuation of error
s[0] = '-';
while (isc_interprete_cpp(s + 1, &vector)) {
if (fb_interpret(s, sizeof(s), &vector))
{
translate_cp(s);
alice_output("%s\n", s);
// Continuation of error
s[0] = '-';
while (fb_interpret(s + 1, sizeof(s) - 1, &vector)) {
translate_cp(s);
alice_output("%s\n", s);
}
}
}
}

View File

@ -1471,7 +1471,7 @@ void BURP_print_status(const ISC_STATUS* status_vector)
**************************************
*
* Functional description
* Print error message. Use isc_interprete_cpp
* Print error message. Use fb_interpret
* to allow redirecting output.
*
**************************************/
@ -1490,11 +1490,11 @@ void BURP_print_status(const ISC_STATUS* status_vector)
#endif
SCHAR s[1024];
if (isc_interprete_cpp(s, &vector)) {
if (fb_interpret(s, sizeof(s), &vector)) {
translate_cp(s);
BURP_msg_partial(256, 0, 0, 0, 0, 0); // msg 256: gbak: ERROR:
burp_output("%s\n", s);
while (isc_interprete_cpp(s, &vector)) {
while (fb_interpret(s, sizeof(s), &vector)) {
translate_cp(s);
BURP_msg_partial(256, 0, 0, 0, 0, 0); // msg 256: gbak: ERROR:
burp_output(" %s\n", s);
@ -1513,7 +1513,7 @@ void BURP_print_warning(const ISC_STATUS* status_vector)
**************************************
*
* Functional description
* Print warning message. Use isc_interprete_cpp
* Print warning message. Use fb_interpret
* to allow redirecting output.
*
**************************************/
@ -1524,11 +1524,11 @@ void BURP_print_warning(const ISC_STATUS* status_vector)
// print the warning message
const ISC_STATUS* vector = &status_vector[2];
SCHAR s[1024];
if (isc_interprete_cpp(s, &vector)) {
if (fb_interpret(s, sizeof(s), &vector)) {
translate_cp(s);
BURP_msg_partial(255, 0, 0, 0, 0, 0); // msg 255: gbak: WARNING:
burp_output("%s\n", s);
while (isc_interprete_cpp(s, &vector)) {
while (fb_interpret(s, sizeof(s), &vector)) {
translate_cp(s);
BURP_msg_partial(255, 0, 0, 0, 0, 0); // msg 255: gbak: WARNING:
burp_output(" %s\n", s);

View File

@ -3348,7 +3348,11 @@ static void send_response( ICC icc, ISC_STATUS* status_vector)
break;
default:
length = (USHORT) isc_interprete(buffer, &status_vector);
{ // scope
const ISC_STATUS* svp = status_vector;
length = (USHORT) fb_interpret(buffer, sizeof(buffer), &svp);
status_vector = const_cast<ISC_STATUS*>(svp);
} // scope
if (!length)
{
*status_vector = 0;

View File

@ -918,15 +918,17 @@ void ISQL_errmsg(const ISC_STATUS* status)
(TEXT*)(IPTR)isc_sqlcode(status), NULL, NULL, NULL, NULL);
TRANSLATE_CP;
STDERROUT(errbuf, 1);
gds_interprete_cpp(errbuf, &vec);
TRANSLATE_CP;
STDERROUT(errbuf, 1);
// Continuation of error
errbuf[0] = '-';
while (gds_interprete_cpp(errbuf + 1, &vec)) {
if (fb_interpret(errbuf, sizeof(errbuf), &vec))
{
TRANSLATE_CP;
STDERROUT(errbuf, 1);
// Continuation of error
errbuf[0] = '-';
while (fb_interpret(errbuf + 1, sizeof(errbuf) - 1, &vec)) {
TRANSLATE_CP;
STDERROUT(errbuf, 1);
}
}
}
}
@ -961,15 +963,17 @@ void ISQL_warning(ISC_STATUS* status)
return;
}
TEXT buf[MSG_LENGTH];
gds_interprete_cpp(buf, &vec);
TRANSLATE_CP;
STDERROUT(buf, 1);
// Continuation of warning
buf[0] = '-';
while (gds_interprete_cpp(buf + 1, &vec)) {
if (fb_interpret(buf, sizeof(buf), &vec))
{
TRANSLATE_CP;
STDERROUT(buf, 1);
// Continuation of warning
buf[0] = '-';
while (fb_interpret(buf + 1, sizeof(buf) - 1, &vec)) {
TRANSLATE_CP;
STDERROUT(buf, 1);
}
}
}
@ -4734,7 +4738,7 @@ static processing_state newdb(TEXT* dbname,
ISQL_FREE(local_psw);
return ERR;
}
TEXT* local_sql_role = (TEXT*) ISQL_ALLOC(BUFFER_LENGTH128);
TEXT* local_sql_role = (TEXT*) ISQL_ALLOC(BUFFER_LENGTH256);
if (!local_sql_role) {
ISQL_FREE(save_database);
ISQL_FREE(errbuf);

View File

@ -713,13 +713,6 @@ SLONG API_ROUTINE isc_interprete(SCHAR* buffer, ISC_STATUS** status_vector_p)
return gds__interprete(buffer, status_vector_p);
}
/* This const params version used in the engine and other places. */
SLONG API_ROUTINE isc_interprete_cpp(SCHAR* const buffer,
const ISC_STATUS** status_vector_p)
{
return gds__interprete(buffer, const_cast<ISC_STATUS**>(status_vector_p));
}
int API_ROUTINE gds__version(
FB_API_HANDLE* db_handle,
FPTR_VERSION_CALLBACK callback,

View File

@ -189,7 +189,6 @@ void API_ROUTINE isc_vtof(const SCHAR*, SCHAR*, USHORT);
void API_ROUTINE isc_vtov(const SCHAR*, SCHAR*, SSHORT);
SLONG API_ROUTINE isc_vax_integer(const SCHAR*, SSHORT);
SLONG API_ROUTINE isc_interprete(SCHAR*, ISC_STATUS**);
SLONG API_ROUTINE isc_interprete_cpp(SCHAR* const, const ISC_STATUS**);
// isc_ functions with no gds_ equivalence
//

View File

@ -249,6 +249,10 @@ static void sanitize(TEXT*);
static void safe_concat_path(TEXT* destbuf, const TEXT* srcbuf);
// New functions that try to be safe.
static SLONG safe_interpret(char* const s, int bufsize, const ISC_STATUS** const vector);
/* Generic cleanup handlers */
struct clean
@ -275,7 +279,8 @@ void* API_ROUTINE gds__alloc_debug(SLONG size_request,
);
}
ULONG API_ROUTINE gds__free(void* blk) {
ULONG API_ROUTINE gds__free(void* blk)
{
getDefaultMemoryPool()->deallocate(blk);
return 0;
}
@ -746,33 +751,38 @@ void API_ROUTINE gds_alloc_report(ULONG flags, const char* filename, int lineno)
// Skidder: Calls to this function must be replaced with MemoryPool::print_contents
}
/* CVC: See comment below. Basically, it provides the needed const correctness,
but throws away the const to make the callee happy, knowing that the callee
indeed treats vector as it was a pointer with the const prefix.
Maybe this function could be private and thus made inline? */
SLONG API_ROUTINE gds_interprete_cpp(char* const s, const ISC_STATUS** vector)
indeed treats vector as it was a pointer with the const prefix. */
/**
fb_interpret
@brief Buffer overrun-aware version of the old gds__interprete
without the double underscore and without the misspelling.
Translate a status code with arguments to a string. Return the
length of the string while updating the vector address. If the
message is null (end of messages) or invalid, return 0;
@param s the output buffer where a human readable version of the error is put
@param bufsize the size of the output buffer
@param vector the input, the address of const pointer to the status vector
that was filled by an API call that reported an error. The function
positions the pointer on the next element of the vector.
**/
SLONG API_ROUTINE fb_interpret(char* const s, int bufsize, const ISC_STATUS** const vector)
{
/**************************************
*
* g d s _ i n t e r p r e t e _ c p p
*
**************************************
*
* Functional description
* Translate a status code with arguments to a string. Return the
* length of the string while updating the vector address. If the
* message is null (end of messages) or invalid, return 0;
*
**************************************/
return gds__interprete(s, const_cast<ISC_STATUS**>(vector));
return safe_interpret(s, bufsize, vector);
}
/* CVC: This non-const signature is needed for compatibility. The reason is
that, unlike int* that can be assigned to const int* transparently to the caller,
int** CANNOT be assigned to const int**, so applications would have to be
fixed to provide such const int**; while it may be more correct from the
semantic POV, we can't estimate how much work it's for app developers.
Therefore, we go back to the old signature and provide gds_interprete_cpp
Therefore, we go back to the old signature and provide fb_interpret
for compliance, to be used inside the engine, too. September, 2003. */
SLONG API_ROUTINE gds__interprete(char* s, ISC_STATUS** vector)
@ -784,12 +794,32 @@ SLONG API_ROUTINE gds__interprete(char* s, ISC_STATUS** vector)
**************************************
*
* Functional description
* Translate a status code with arguments to a string. Return the
* length of the string while updating the vector address. If the
* message is null (end of messages) or invalid, return 0;
* See safe_interpret for details. Now this is a wrapper for that function.
* CVC: Since this routine doesn't get the size of the input buffer,
* it's DEPRECATED and we'll assume the buffer size was twice MAXPATHLEN.
*
**************************************/
if (!**vector)
return safe_interpret(s, MAXPATHLEN < 1, const_cast<const ISC_STATUS**>(vector));
}
/**
safe_interpret
@brief Translate a status code with arguments to a string. Return the
length of the string while updating the vector address. If the
message is null (end of messages) or invalid, return 0;
@param s the output buffer where a human readable version of the error is put
@param bufsize the size of the output buffer
@param vector the input, the address of const pointer to the status vector
that was filled by an API call that reported an error. The function
positions the pointer on the next element of the vector.
**/
static SLONG safe_interpret(char* const s, int bufsize, const ISC_STATUS** const vector)
{
if (!**vector || bufsize < 1)
return 0;
const ISC_STATUS* v;
@ -809,15 +839,17 @@ SLONG API_ROUTINE gds__interprete(char* s, ISC_STATUS** vector)
/* Parse and collect any arguments that may be present */
TEXT* p;
TEXT* p = 0;
const TEXT* q;
const SSHORT temp_len = (SSHORT) BUFFER_SMALL;
TEXT* temp = NULL;
SSHORT l;
for (;;) {
for (;;)
{
const UCHAR x = (UCHAR) *v++;
switch (x) {
switch (x)
{
case isc_arg_string:
case isc_arg_number:
*arg++ = (TEXT*) *v++;
@ -934,15 +966,15 @@ SLONG API_ROUTINE gds__interprete(char* s, ISC_STATUS** vector)
default:
if (temp)
gds__free((SLONG *) temp);
gds__free(temp);
return 0;
}
if (temp)
gds__free((SLONG *) temp);
gds__free(temp);
*vector = const_cast<ISC_STATUS*>(v);
*vector = v;
const TEXT* end = s;
while (*end)
end++;
@ -1234,10 +1266,8 @@ void API_ROUTINE gds__log_status(const TEXT* database,
fb_assert(db_len < MAXPATHLEN);
#endif
const int interpreted_line_length = 80; // raw estimation
TEXT* p = buffer;
const TEXT* const end = p + BUFFER_XLARGE - interpreted_line_length;
const TEXT* const end = p + BUFFER_XLARGE;
const int max_db_len = int(BUFFER_XLARGE - 12);
sprintf(p, "Database: %.*s", max_db_len, (database) ? database : "");
@ -1247,7 +1277,7 @@ void API_ROUTINE gds__log_status(const TEXT* database,
*p++ = '\n';
*p++ = '\t';
} while (p < end && gds_interprete_cpp(p, &status_vector));
} while (p < end && safe_interpret(p, end - p, &status_vector));
p[-2] = 0;
gds__log(buffer, 0);
@ -1922,7 +1952,7 @@ ISC_STATUS API_ROUTINE gds__print_status(const ISC_STATUS* vec)
const ISC_STATUS* vector = vec;
if (!gds_interprete_cpp(s, &vector)) {
if (!safe_interpret(s, BUFFER_LARGE, &vector)) {
gds__free((SLONG *) s);
return vec[1];
}
@ -1930,7 +1960,7 @@ ISC_STATUS API_ROUTINE gds__print_status(const ISC_STATUS* vec)
gds__put_error(s);
s[0] = '-';
while (gds_interprete_cpp(s + 1, &vector))
while (safe_interpret(s + 1, BUFFER_LARGE - 1, &vector))
gds__put_error(s);
gds__free((void*) s);

View File

@ -72,8 +72,9 @@ void API_ROUTINE isc_encode_timestamp(const void*, GDS_TIMESTAMP*);
ULONG API_ROUTINE gds__free(void*);
/* CVC: This function was created to be used inside the engine, but I don't see
a problem if it's used from outside, too. */
SLONG API_ROUTINE gds_interprete_cpp(char* const, const ISC_STATUS**);
a problem if it's used from outside, too.
This function has been renamed and made public. */
SLONG API_ROUTINE fb_interpret(char* const, int, const ISC_STATUS** const);
/* CVC: This non-const signature is needed for compatibility, see gds.cpp. */
SLONG API_ROUTINE gds__interprete(char*, ISC_STATUS**);
void API_ROUTINE gds__interprete_a(SCHAR*, SSHORT*, ISC_STATUS*, SSHORT*);

View File

@ -33,7 +33,7 @@
*
*/
/*
$Id: ibase.h,v 1.86 2004-09-10 04:50:25 robocop Exp $
$Id: ibase.h,v 1.87 2004-09-22 01:59:20 robocop Exp $
*/
#ifndef JRD_IBASE_H
@ -563,8 +563,9 @@ ISC_LONG ISC_EXPORT isc_interprete(ISC_SCHAR*,
ISC_STATUS**);
/* This const params version used in the engine and other places. */
ISC_LONG ISC_EXPORT isc_interprete_cpp(ISC_SCHAR* const,
const ISC_STATUS**);
ISC_LONG ISC_EXPORT fb_interpret(ISC_SCHAR* const,
int,
const ISC_STATUS** const);
ISC_STATUS ISC_EXPORT isc_open_blob(ISC_STATUS*,
isc_db_handle*,

View File

@ -167,6 +167,7 @@ entry(gds__attach_database)
entry(isc_get_segment)
entry(isc_get_slice)
entry(isc_interprete)
entry(fb_interpret)
entry(isc_open_blob)
entry(isc_open_blob2)
entry(ISC_prefix)

View File

@ -679,7 +679,7 @@ void PrintCfgStatus(const ISC_STATUS* status_vector, int nErrCode, HWND hDlg)
**************************************
*
* Functional description
* Print error message. Use isc_interprete_cpp
* Print error message. Use fb_interpret
* to allow redirecting output.
*
**************************************/
@ -690,18 +690,33 @@ void PrintCfgStatus(const ISC_STATUS* status_vector, int nErrCode, HWND hDlg)
if (status_vector) {
const ISC_STATUS* vector = status_vector;
if (isc_interprete_cpp(szErrStr, &vector)) {
if (fb_interpret(szErrStr, sizeof(szErrStr), &vector))
{
SCHAR *ptr = szErrStr + strlen(szErrStr);
const char* const szEnd = szErrStr + sizeof(szErrStr);
*ptr++ = '\r';
*ptr++ = '\n';
*ptr++ = '-';
while (isc_interprete_cpp(ptr, &vector)) {
ptr += strlen(ptr);
*ptr++ = '\r';
if (ptr < szEnd - 1)
{
*ptr++ = '\n';
*ptr++ = '-';
}
else
ptr += 2;
while (ptr < szEnd && fb_interpret(ptr, szEnd - ptr, &vector))
{
ptr += strlen(ptr);
*ptr++ = '\r';
if (ptr < szEnd - 1)
{
*ptr++ = '\n';
*ptr++ = '-';
}
else {
ptr += 2;
break;
}
}
*(ptr - 3) = '\0';
}
}

View File

@ -4087,6 +4087,7 @@ ISC_STATUS rem_port::send_response( PACKET* sendL,
ISC_STATUS_ARRAY new_vector;
ISC_STATUS* v = new_vector;
TEXT buffer[1024];
const char* const bufferEnd = buffer + sizeof(buffer);
TEXT* p = buffer;
const ISC_STATUS exit_code = status_vector[1];
@ -4161,9 +4162,11 @@ ISC_STATUS rem_port::send_response( PACKET* sendL,
*v++ = *status_vector++;
continue;
}
const USHORT l = (USHORT) isc_interprete_cpp(p, &status_vector);
const USHORT l = p < bufferEnd ?
(USHORT) fb_interpret(p, bufferEnd - p, &status_vector) : 0;
if (l == 0)
break;
*v++ = isc_arg_interpreted;
TEXT** sp = (TEXT**) v;
*sp++ = p;

View File

@ -1114,7 +1114,7 @@ void GSEC_print_status(const ISC_STATUS* status_vector)
**************************************
*
* Functional description
* Print error message. Use isc_interprete_cpp
* Print error message. Use fb_interpret
* to allow redirecting output.
*
**************************************/
@ -1133,10 +1133,10 @@ void GSEC_print_status(const ISC_STATUS* status_vector)
#endif
SCHAR s[1024];
if (isc_interprete_cpp(s, &vector)) {
if (fb_interpret(s, sizeof(s), &vector)) {
TRANSLATE_CP(s);
util_output("%s\n", s);
while (isc_interprete_cpp(s, &vector)) {
while (fb_interpret(s, sizeof(s), &vector)) {
TRANSLATE_CP(s);
util_output("%s\n", s);
}

View File

@ -902,11 +902,11 @@ int CLIB_ROUTINE main(int argc, char** argv)
#endif
const ISC_STATUS* vector = status_vector;
SCHAR s[1024];
if (isc_interprete_cpp(s, &vector))
if (fb_interpret(s, sizeof(s), &vector))
{
FPRINTF(tddba->sw_outfile, "%s\n", s);
s[0] = '-';
while (isc_interprete_cpp(s + 1, &vector)) {
while (fb_interpret(s + 1, sizeof(s) - 1, &vector)) {
FPRINTF(tddba->sw_outfile, "%s\n", s);
}
}