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:
parent
d6159be71c
commit
38a973d2b1
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user