s3-rpc_server: Fix handling of fragmented rpc requests.
authorAndreas Schneider <asn@cryptomilk.org>
Thu, 20 Mar 2014 13:45:01 +0000 (14:45 +0100)
committerGünther Deschner <gd@samba.org>
Thu, 20 Mar 2014 17:30:17 +0000 (18:30 +0100)
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 <metze@samba.org>
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Guenther Deschner <gd@samba.org
Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Thu Mar 20 18:30:17 CET 2014 on sn-devel-104

source3/rpc_server/srv_pipe.c

index 36864d26045f189ce6dffb20b95fa2b1219adecf..67c9a68b98429ed8d44efa8939340ef469c5f408 100644 (file)
@@ -1547,9 +1547,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);
 }
@@ -1563,6 +1560,10 @@ void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
 
        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);
@@ -1595,9 +1596,7 @@ void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
                /*
                 * 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:
@@ -1612,9 +1611,7 @@ void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
                /*
                 * 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:
@@ -1626,9 +1623,7 @@ void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
                /*
                 * 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:
@@ -1676,6 +1671,7 @@ void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
                break;
        }
 
+done:
        if (!reply) {
                DEBUG(3,("DCE/RPC fault sent!"));
                set_incoming_fault(p);