From 44cf46b0bbb0abf5aebfbf2f2da713da65573175 Mon Sep 17 00:00:00 2001 From: Gregor Beck Date: Thu, 9 Jan 2014 10:15:31 +0100 Subject: [PATCH 1/2] s3:rpc_server: minor refactoring of process_request_pdu() Signed-off-by: Gregor Beck Reviewed-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit b5f30205931a4b9d0b3b257d5855869e606f8b63) --- source3/rpc_server/srv_pipe.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 894f12c..a5b74ed 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1561,24 +1561,19 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt } } - if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) { - bool ret = False; - /* - * Ok - we finally have a complete RPC stream. - * Call the rpc command to process it. - */ - - /* - * Process the complete data stream here. - */ - if (pipe_init_outgoing_data(p)) { - ret = api_pipe_request(p, pkt); - } + if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { + return true; + } - return ret; + /* + * Ok - we finally have a complete RPC stream. + * Call the rpc command to process it. + */ + if (!pipe_init_outgoing_data(p)) { + return false; } - return True; + return api_pipe_request(p, pkt); } /**************************************************************************** -- 1.9.0 From 436aa053561b9b6ff4b991bf6a2f5196ed39dd38 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 20 Mar 2014 14:45:01 +0100 Subject: [PATCH 2/2] s3-rpc_server: Fix handling of fragmented rpc requests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to call pipe_init_outgoing_data() as the first thing in process_complete_pdu(). Otherwise the caller may use uninitialized memory and tries to write a response into the socket. The problem happens only if a real socket is used, which means in all cases for master and only with external rpc daemons in v4-0 and v4-1. The problem looks like this in the logs. [2014/03/20 14:49:35.531663, 10, pid=7309, effective(0, 0), real(0, 0), class=rpc_srv] ../source3/rpc_server/srv_pipe.c:1627(process_complete_pdu) Processing packet type 0 [2014/03/20 14:49:35.531695, 10, pid=7309, effective(0, 0), real(0, 0), class=rpc_srv] ../source3/rpc_server/srv_pipe.c:1472(dcesrv_auth_request) Checking request auth. [2014/03/20 14:49:35.531738, 10, pid=7309, effective(0, 0), real(0, 0)] ../source3/rpc_server/rpc_server.c:521(named_pipe_packet_process) Sending 1 fragments in a total of 0 bytes [2014/03/20 14:49:35.531769, 10, pid=7309, effective(0, 0), real(0, 0)] ../source3/rpc_server/rpc_server.c:526(named_pipe_packet_process) Sending PDU number: 0, PDU Length: 4294967228 [2014/03/20 14:49:35.531801, 2, pid=7309, effective(0, 0), real(0, 0)] ../source3/rpc_server/rpc_server.c:565(named_pipe_packet_done) Writev failed! [2014/03/20 14:49:35.531845, 2, pid=7309, effective(0, 0), real(0, 0)] ../source3/rpc_server/rpc_server.c:595(named_pipe_packet_done) Fatal error(Message too long). Terminating client(127.0.0.1) connection! BUG: https://bugzilla.samba.org/show_bug.cgi?id=10481 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Andreas Schneider Reviewed-by: Guenther Deschner Autobuild-Date(master): Thu Mar 20 18:30:17 CET 2014 on sn-devel-104 (cherry picked from commit 5277fc4d0393ffe2e415ad26610b36d2986c62d7) --- source3/rpc_server/srv_pipe.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a5b74ed..7daff04 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1569,9 +1569,6 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt * Ok - we finally have a complete RPC stream. * Call the rpc command to process it. */ - if (!pipe_init_outgoing_data(p)) { - return false; - } return api_pipe_request(p, pkt); } @@ -1621,6 +1618,10 @@ void process_complete_pdu(struct pipes_struct *p) DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype)); + if (!pipe_init_outgoing_data(p)) { + goto done; + } + switch (pkt->ptype) { case DCERPC_PKT_REQUEST: reply = process_request_pdu(p, pkt); @@ -1653,9 +1654,7 @@ void process_complete_pdu(struct pipes_struct *p) /* * We assume that a pipe bind is only in one pdu. */ - if (pipe_init_outgoing_data(p)) { - reply = api_pipe_bind_req(p, pkt); - } + reply = api_pipe_bind_req(p, pkt); break; case DCERPC_PKT_BIND_ACK: @@ -1670,9 +1669,7 @@ void process_complete_pdu(struct pipes_struct *p) /* * We assume that a pipe bind is only in one pdu. */ - if (pipe_init_outgoing_data(p)) { - reply = api_pipe_alter_context(p, pkt); - } + reply = api_pipe_alter_context(p, pkt); break; case DCERPC_PKT_ALTER_RESP: @@ -1684,9 +1681,7 @@ void process_complete_pdu(struct pipes_struct *p) /* * The third packet in an auth exchange. */ - if (pipe_init_outgoing_data(p)) { - reply = api_pipe_bind_auth3(p, pkt); - } + reply = api_pipe_bind_auth3(p, pkt); break; case DCERPC_PKT_SHUTDOWN: -- 1.9.0