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

Let's fix the cause instead of the effect. No more buffer overflows.

This commit is contained in:
dimitr 2003-07-15 13:35:23 +00:00
parent d6159be71c
commit 38a973d2b1

View File

@ -254,28 +254,7 @@ BOOLEAN OPT_access_path(JRD_REQ request,
DEV_BLKCHK(request, type_req); DEV_BLKCHK(request, type_req);
// dimitr: dump_xxx routines may overrun the passed buffer before SCHAR * begin = buffer;
// returning FALSE. Yes, we live in the very cruel world.
// Since INF_request_info uses quite small stack buffer
// by default, any non-trivial access path may lead to
// memory corruption. Below we allocate as much memory as
// looks to be safe (I don't have a clue how much memory
// we should have reserved in the tail of the buffer, but
// think 256 bytes should be enough), work with it and
// only if the final result is TRUE we write data to the
// high level buffer.
//
// P.S. I don't like it much to deal with pool allocations here
// but our buffer is freed immediately and GDS_REQUEST_INFO
// isn't a most commonly used routine, so probably my
// worries shouldn't be taken seriously. Stack allocations
// shouldn't be used here, because OPT_access_path can be
// called recursively.
SCHAR * temp_buffer = (SCHAR*) gds__alloc(BUFFER_XLARGE + 256);
SCHAR * ptr = temp_buffer;
USHORT length = 0;
/* loop through all RSEs in the request, /* loop through all RSEs in the request,
and describe the rsb tree for that rsb; and describe the rsb tree for that rsb;
@ -288,20 +267,16 @@ BOOLEAN OPT_access_path(JRD_REQ request,
for (i = vector->count() - 1; i >= 0; i--) { for (i = vector->count() - 1; i >= 0; i--) {
rsb = (RSB) (*vector)[i]; rsb = (RSB) (*vector)[i];
if (rsb && !dump_rsb(request, rsb, &ptr, &buffer_length)) if (rsb && !dump_rsb(request, rsb, &buffer, &buffer_length))
break; break;
} }
if (i < 0) { *return_length = buffer - begin;
length = ptr - temp_buffer;
memcpy(buffer, temp_buffer, length);
}
*return_length = length; if (i >= 0)
return FALSE;
gds__free(temp_buffer); else
return TRUE;
return (length > 0);
} }
@ -2209,12 +2184,13 @@ static BOOLEAN dump_index(JRD_NOD node,
(USHORT) (retrieval->irb_index + 1)); (USHORT) (retrieval->irb_index + 1));
length = strlen(index_name); length = strlen(index_name);
if ((*buffer_length -= (length + 1)) >= 0) { *buffer_length -= 1 + length;
*buffer++ = (SCHAR) length; if (*buffer_length < 0)
i = index_name; return FALSE;
while (length--) *buffer++ = (SCHAR) length;
*buffer++ = *i++; i = index_name;
} while (length--)
*buffer++ = *i++;
} }
*buffer_ptr = buffer; *buffer_ptr = buffer;
@ -2251,7 +2227,8 @@ static BOOLEAN dump_rsb(JRD_REQ request,
/* leave room for the rsb begin, type, and end */ /* leave room for the rsb begin, type, and end */
if ((*buffer_length -= 4) < 0) *buffer_length -= 4;
if (*buffer_length < 0)
return FALSE; return FALSE;
*buffer++ = gds_info_rsb_begin; *buffer++ = gds_info_rsb_begin;
@ -2288,8 +2265,6 @@ static BOOLEAN dump_rsb(JRD_REQ request,
*buffer++ = gds_info_rsb_indexed; *buffer++ = gds_info_rsb_indexed;
if (!dump_index((JRD_NOD) rsb->rsb_arg[0], &buffer, buffer_length)) if (!dump_index((JRD_NOD) rsb->rsb_arg[0], &buffer, buffer_length))
return FALSE; return FALSE;
if (--(*buffer_length) < 0)
return FALSE;
break; break;
case rsb_navigate: case rsb_navigate:
@ -2297,8 +2272,6 @@ static BOOLEAN dump_rsb(JRD_REQ request,
if (!dump_index if (!dump_index
((JRD_NOD) rsb->rsb_arg[RSB_NAV_index], &buffer, ((JRD_NOD) rsb->rsb_arg[RSB_NAV_index], &buffer,
buffer_length)) return FALSE; buffer_length)) return FALSE;
if (--(*buffer_length) < 0)
return FALSE;
break; break;
case rsb_sequential: case rsb_sequential:
@ -2334,7 +2307,7 @@ static BOOLEAN dump_rsb(JRD_REQ request,
if (!procedure->prc_request->req_fors) { if (!procedure->prc_request->req_fors) {
STR n = procedure->prc_name; STR n = procedure->prc_name;
length = (n && n->str_data) ? n->str_length : 0; length = (n && n->str_data) ? n->str_length : 0;
*buffer_length -= 5 + length; *buffer_length -= 6 + length;
if (*buffer_length < 0) if (*buffer_length < 0)
return FALSE; return FALSE;
*buffer++ = gds_info_rsb_begin; *buffer++ = gds_info_rsb_begin;
@ -2345,7 +2318,6 @@ static BOOLEAN dump_rsb(JRD_REQ request,
*buffer++ = *name++; *buffer++ = *name++;
*buffer++ = gds_info_rsb_type; *buffer++ = gds_info_rsb_type;
*buffer++ = gds_info_rsb_sequential; *buffer++ = gds_info_rsb_sequential;
/* *buffer++ = gds__info_rsb_unknown; */
*buffer++ = gds_info_rsb_end; *buffer++ = gds_info_rsb_end;
break; break;
} }
@ -2354,7 +2326,8 @@ static BOOLEAN dump_rsb(JRD_REQ request,
(procedure->prc_request, buffer, *buffer_length, (procedure->prc_request, buffer, *buffer_length,
reinterpret_cast < USHORT * >(&return_length))) reinterpret_cast < USHORT * >(&return_length)))
return FALSE; return FALSE;
if ((*buffer_length -= return_length) < 0) *buffer_length -= return_length;
if (*buffer_length < 0)
return FALSE; return FALSE;
buffer += return_length; buffer += return_length;
break; break;
@ -2428,6 +2401,9 @@ static BOOLEAN dump_rsb(JRD_REQ request,
and merge, dump out the count of streams first, then and merge, dump out the count of streams first, then
loop through the substreams and dump them out */ loop through the substreams and dump them out */
if (--(*buffer_length) < 0)
return FALSE;
switch (rsb->rsb_type) { switch (rsb->rsb_type) {
case rsb_cross: case rsb_cross:
*buffer++ = (UCHAR) rsb->rsb_count; *buffer++ = (UCHAR) rsb->rsb_count;
@ -2462,8 +2438,9 @@ static BOOLEAN dump_rsb(JRD_REQ request,
(request, rsb->rsb_arg[RSB_LEFT_inner], &buffer, (request, rsb->rsb_arg[RSB_LEFT_inner], &buffer,
buffer_length)) return FALSE; buffer_length)) return FALSE;
break; break;
default: /* Shut up compiler warnings */
break; default: /* Shut up compiler warnings */
break;
} }
/* dump out the next rsb */ /* dump out the next rsb */