Skip to content

Commit

Permalink
Fixed CORE-2563: Possible DoS attack using the malformed packet sent …
Browse files Browse the repository at this point in the history
…into the connection port.

Backported the port context validation that prevents non-authorized packets from crashing the server.
  • Loading branch information
dyemanov committed Jul 20, 2009
1 parent f224214 commit 0964cde
Showing 1 changed file with 119 additions and 1 deletion.
120 changes: 119 additions & 1 deletion src/remote/server.cpp
Expand Up @@ -167,6 +167,20 @@ static int THREAD_ROUTINE thread(void *);
static void zap_packet(PACKET*, BOOLEAN);


static bool bad_port_context(ISC_STATUS*, RDB, const ISC_LONG);


inline bool bad_db(ISC_STATUS* status_vector, RDB rdb)
{
return bad_port_context(status_vector, rdb, isc_bad_db_handle);
}

inline bool bad_service(ISC_STATUS* status_vector, RDB rdb)
{
return bad_port_context(status_vector, rdb, isc_bad_svc_handle);
}


// static data - NOT THREAD SAFE!

static SLONG threads_waiting = 0;
Expand Down Expand Up @@ -644,6 +658,11 @@ static ISC_STATUS allocate_statement( PORT port, P_RLSE * allocate, PACKET* send
ISC_STATUS_ARRAY status_vector;

rdb = port->port_context;
if (bad_db(status_vector, rdb))
{
return port->send_response(send, 0, 0, status_vector);
}

handle = NULL;

THREAD_EXIT;
Expand Down Expand Up @@ -876,14 +895,21 @@ static void aux_request( PORT port, P_REQ * request, PACKET* send)
port->port_status_vector = status_vector;
success(status_vector);

rdb = port->port_context;
if (bad_db(status_vector, rdb))
{
port->send_response(send, 0, 0, status_vector);
return;
}

/* We do this silliness with buffer because the SPX protocol
requires a 12 byte buffer to be sent back. Other protocols
can do what they want to with cstr_address. */

save_cstring = send->p_resp.p_resp_data;
send->p_resp.p_resp_data.cstr_address = buffer;
aux_port = port->request(send);
rdb = port->port_context;

port->send_response(send, rdb->rdb_id,
send->p_resp.p_resp_data.cstr_length, status_vector);

Expand Down Expand Up @@ -927,6 +953,10 @@ static ISC_STATUS cancel_events( PORT port, P_EVENT * stuff, PACKET* send)
/* Which database ? */

rdb = port->port_context;
if (bad_db(status_vector, rdb))
{
return port->send_response(send, 0, 0, status_vector);
}

/* Find the event */

Expand Down Expand Up @@ -1109,6 +1139,11 @@ ISC_STATUS port::compile(P_CMPL* compile, PACKET* send)
OBJCT object;

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

handle = NULL;
blr = compile->p_cmpl_blr.cstr_address;
blr_length = compile->p_cmpl_blr.cstr_length;
Expand Down Expand Up @@ -1204,6 +1239,11 @@ ISC_STATUS port::ddl(P_DDL* ddl, PACKET* send)
isc_bad_trans_handle);

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

blr = ddl->p_ddl_blr.cstr_address;
blr_length = ddl->p_ddl_blr.cstr_length;

Expand Down Expand Up @@ -1408,6 +1448,11 @@ void port::drop_database(P_RLSE* release, PACKET* send)
ISC_STATUS_ARRAY status_vector;

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
this->send_response(send, 0, 0, status_vector);
return;
}

THREAD_EXIT;
isc_drop_database(status_vector,
Expand Down Expand Up @@ -1525,6 +1570,10 @@ ISC_STATUS port::end_database(P_RLSE * release, PACKET* send)
ISC_STATUS_ARRAY status_vector;

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

THREAD_EXIT;
isc_detach_database(status_vector,
Expand Down Expand Up @@ -1717,6 +1766,10 @@ ISC_STATUS port::execute_immediate(P_OP op, P_SQLST * exnow, PACKET* send)
ISC_STATUS_ARRAY status_vector;

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

/** Do not call CHECK_HANDLE if this is the start of a transaction **/
if (this->port_objects && exnow->p_sqlst_transaction) {
Expand Down Expand Up @@ -2482,6 +2535,11 @@ ISC_STATUS port::get_slice(P_SLC * stuff, PACKET* send)
UCHAR temp_buffer[4096];

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

CHECK_HANDLE_MEMBER(transaction,
RTR,
type_rtr,
Expand Down Expand Up @@ -2568,6 +2626,10 @@ ISC_STATUS port::info(P_OP op, P_INFO * stuff, PACKET* send)
ISC_STATUS_ARRAY status_vector;

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

/* Make sure there is a suitable temporary blob buffer */

Expand Down Expand Up @@ -2822,6 +2884,11 @@ ISC_STATUS port::open_blob(P_OP op, P_BLOB * stuff, PACKET* send)
isc_bad_trans_handle);

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

handle = NULL;
bpb_length = 0;
bpb = NULL;
Expand Down Expand Up @@ -3407,6 +3474,10 @@ ISC_STATUS port::put_slice(P_SLC * stuff, PACKET* send)
isc_bad_trans_handle);

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

THREAD_EXIT;
send->p_resp.p_resp_blob_id = stuff->p_slc_id;
Expand Down Expand Up @@ -3443,6 +3514,10 @@ ISC_STATUS port::que_events(P_EVENT * stuff, PACKET* send)
SLONG id;

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

/* Find unused event block or, if necessary, a new one */

Expand Down Expand Up @@ -4471,6 +4546,10 @@ ISC_STATUS port::service_end(P_RLSE * release, PACKET* send)
ISC_STATUS_ARRAY status_vector;

RDB rdb = this->port_context;
if (bad_service(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

THREAD_EXIT;
isc_service_detach(status_vector,
Expand Down Expand Up @@ -4498,6 +4577,10 @@ ISC_STATUS port::service_start(P_INFO * stuff, PACKET* send)
ULONG *reserved = 0; /* reserved for future use */

rdb = this->port_context;
if (bad_service(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

THREAD_EXIT;
isc_service_start(status_vector,
Expand Down Expand Up @@ -4702,6 +4785,11 @@ ISC_STATUS port::start_transaction(P_OP operation, P_STTR * stuff, PACKET* send)
ISC_STATUS_ARRAY status_vector;

RDB rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

FRBRD *handle = NULL;

THREAD_EXIT;
Expand Down Expand Up @@ -4975,6 +5063,11 @@ ISC_STATUS port::transact_request(P_TRRQ * trrq, PACKET* send)
isc_bad_trans_handle);

rdb = this->port_context;
if (bad_db(status_vector, rdb))
{
return this->send_response(send, 0, 0, status_vector);
}

blr = trrq->p_trrq_blr.cstr_address;
blr_length = trrq->p_trrq_blr.cstr_length;
procedure = this->port_rpr;
Expand Down Expand Up @@ -5037,3 +5130,28 @@ static void zap_packet( PACKET* packet, BOOLEAN new_)
memset(packet, 0, sizeof(PACKET));
#endif
}


static bool bad_port_context(ISC_STATUS* status_vector,
RDB rdb,
const ISC_LONG error)
{
/**************************************
*
* b a d _ p o r t _ c o n t e x t
*
**************************************
*
* Functional description
* Check rdb pointer, in case of error create status vector
*
**************************************/
if (rdb)
{
return false;
}
status_vector[0] = isc_arg_gds;
status_vector[1] = error;
status_vector[2] = isc_arg_end;
return true;
}

0 comments on commit 0964cde

Please sign in to comment.