8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 05:23: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);
// dimitr: dump_xxx routines may overrun the passed buffer before
// 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;
SCHAR * begin = buffer;
/* loop through all RSEs in the request,
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--) {
rsb = (RSB) (*vector)[i];
if (rsb && !dump_rsb(request, rsb, &ptr, &buffer_length))
if (rsb && !dump_rsb(request, rsb, &buffer, &buffer_length))
break;
}
if (i < 0) {
length = ptr - temp_buffer;
memcpy(buffer, temp_buffer, length);
}
*return_length = buffer - begin;
*return_length = length;
gds__free(temp_buffer);
return (length > 0);
if (i >= 0)
return FALSE;
else
return TRUE;
}
@ -2209,12 +2184,13 @@ static BOOLEAN dump_index(JRD_NOD node,
(USHORT) (retrieval->irb_index + 1));
length = strlen(index_name);
if ((*buffer_length -= (length + 1)) >= 0) {
*buffer++ = (SCHAR) length;
i = index_name;
while (length--)
*buffer++ = *i++;
}
*buffer_length -= 1 + length;
if (*buffer_length < 0)
return FALSE;
*buffer++ = (SCHAR) length;
i = index_name;
while (length--)
*buffer++ = *i++;
}
*buffer_ptr = buffer;
@ -2251,7 +2227,8 @@ static BOOLEAN dump_rsb(JRD_REQ request,
/* leave room for the rsb begin, type, and end */
if ((*buffer_length -= 4) < 0)
*buffer_length -= 4;
if (*buffer_length < 0)
return FALSE;
*buffer++ = gds_info_rsb_begin;
@ -2288,8 +2265,6 @@ static BOOLEAN dump_rsb(JRD_REQ request,
*buffer++ = gds_info_rsb_indexed;
if (!dump_index((JRD_NOD) rsb->rsb_arg[0], &buffer, buffer_length))
return FALSE;
if (--(*buffer_length) < 0)
return FALSE;
break;
case rsb_navigate:
@ -2297,8 +2272,6 @@ static BOOLEAN dump_rsb(JRD_REQ request,
if (!dump_index
((JRD_NOD) rsb->rsb_arg[RSB_NAV_index], &buffer,
buffer_length)) return FALSE;
if (--(*buffer_length) < 0)
return FALSE;
break;
case rsb_sequential:
@ -2334,7 +2307,7 @@ static BOOLEAN dump_rsb(JRD_REQ request,
if (!procedure->prc_request->req_fors) {
STR n = procedure->prc_name;
length = (n && n->str_data) ? n->str_length : 0;
*buffer_length -= 5 + length;
*buffer_length -= 6 + length;
if (*buffer_length < 0)
return FALSE;
*buffer++ = gds_info_rsb_begin;
@ -2345,7 +2318,6 @@ static BOOLEAN dump_rsb(JRD_REQ request,
*buffer++ = *name++;
*buffer++ = gds_info_rsb_type;
*buffer++ = gds_info_rsb_sequential;
/* *buffer++ = gds__info_rsb_unknown; */
*buffer++ = gds_info_rsb_end;
break;
}
@ -2354,7 +2326,8 @@ static BOOLEAN dump_rsb(JRD_REQ request,
(procedure->prc_request, buffer, *buffer_length,
reinterpret_cast < USHORT * >(&return_length)))
return FALSE;
if ((*buffer_length -= return_length) < 0)
*buffer_length -= return_length;
if (*buffer_length < 0)
return FALSE;
buffer += return_length;
break;
@ -2428,6 +2401,9 @@ static BOOLEAN dump_rsb(JRD_REQ request,
and merge, dump out the count of streams first, then
loop through the substreams and dump them out */
if (--(*buffer_length) < 0)
return FALSE;
switch (rsb->rsb_type) {
case rsb_cross:
*buffer++ = (UCHAR) rsb->rsb_count;
@ -2462,8 +2438,9 @@ static BOOLEAN dump_rsb(JRD_REQ request,
(request, rsb->rsb_arg[RSB_LEFT_inner], &buffer,
buffer_length)) return FALSE;
break;
default: /* Shut up compiler warnings */
break;
default: /* Shut up compiler warnings */
break;
}
/* dump out the next rsb */