CVE-2015-5370: s3:rpc_server: make use of dcerpc_verify_ncacn_packet_header() to...
authorStefan Metzmacher <metze@samba.org>
Tue, 7 Jul 2015 14:06:59 +0000 (16:06 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 30 Mar 2016 02:10:14 +0000 (04:10 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
source3/rpc_server/srv_pipe.c

index a1304d3753b68a1fe2e8c8dbcb55f7f024c6ba80..ad4b7a865b0c460469db350f94c682d263f81073 100644 (file)
@@ -30,7 +30,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "srv_pipe_internal.h"
-#include "../librpc/gen_ndr/dcerpc.h"
+#include "../librpc/gen_ndr/ndr_dcerpc.h"
 #include "../librpc/rpc/rpc_common.h"
 #include "dcesrv_auth_generic.h"
 #include "rpc_server.h"
@@ -645,6 +645,25 @@ static bool api_pipe_bind_req(struct pipes_struct *p,
        }
        p->allow_bind = false;
 
+       status = dcerpc_verify_ncacn_packet_header(pkt,
+                       DCERPC_PKT_BIND,
+                       pkt->u.bind.auth_info.length,
+                       0, /* required flags */
+                       DCERPC_PFC_FLAG_FIRST |
+                       DCERPC_PFC_FLAG_LAST |
+                       DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
+                       0x08 | /* this is not defined, but should be ignored */
+                       DCERPC_PFC_FLAG_CONC_MPX |
+                       DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
+                       DCERPC_PFC_FLAG_MAYBE |
+                       DCERPC_PFC_FLAG_OBJECT_UUID);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n",
+                         nt_errstr(status)));
+               NDR_PRINT_DEBUG(ncacn_packet, pkt);
+               goto err_exit;
+       }
+
        if (pkt->u.bind.num_contexts == 0) {
                DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n"));
                goto err_exit;
@@ -887,6 +906,25 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
                goto err;
        }
 
+       status = dcerpc_verify_ncacn_packet_header(pkt,
+                       DCERPC_PKT_AUTH3,
+                       pkt->u.auth3.auth_info.length,
+                       0, /* required flags */
+                       DCERPC_PFC_FLAG_FIRST |
+                       DCERPC_PFC_FLAG_LAST |
+                       DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
+                       0x08 | /* this is not defined, but should be ignored */
+                       DCERPC_PFC_FLAG_CONC_MPX |
+                       DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
+                       DCERPC_PFC_FLAG_MAYBE |
+                       DCERPC_PFC_FLAG_OBJECT_UUID);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n",
+                         nt_errstr(status)));
+               NDR_PRINT_DEBUG(ncacn_packet, pkt);
+               goto err;
+       }
+
        /* We can only finish if the pipe is unbound for now */
        if (p->pipe_bound) {
                DEBUG(0, (__location__ ": Pipe already bound, "
@@ -993,6 +1031,25 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
                goto err_exit;
        }
 
+       status = dcerpc_verify_ncacn_packet_header(pkt,
+                       DCERPC_PKT_ALTER,
+                       pkt->u.alter.auth_info.length,
+                       0, /* required flags */
+                       DCERPC_PFC_FLAG_FIRST |
+                       DCERPC_PFC_FLAG_LAST |
+                       DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
+                       0x08 | /* this is not defined, but should be ignored */
+                       DCERPC_PFC_FLAG_CONC_MPX |
+                       DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
+                       DCERPC_PFC_FLAG_MAYBE |
+                       DCERPC_PFC_FLAG_OBJECT_UUID);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n",
+                         nt_errstr(status)));
+               NDR_PRINT_DEBUG(ncacn_packet, pkt);
+               goto err_exit;
+       }
+
        if (pkt->u.alter.num_contexts == 0) {
                DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n"));
                goto err_exit;
@@ -1476,6 +1533,29 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt
                return False;
        }
 
+       /*
+        * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL.
+        * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later.
+        */
+       status = dcerpc_verify_ncacn_packet_header(pkt,
+                       DCERPC_PKT_REQUEST,
+                       pkt->u.request.stub_and_verifier.length,
+                       0, /* required_flags */
+                       DCERPC_PFC_FLAG_FIRST |
+                       DCERPC_PFC_FLAG_LAST |
+                       0x08 | /* this is not defined, but should be ignored */
+                       DCERPC_PFC_FLAG_CONC_MPX |
+                       DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
+                       DCERPC_PFC_FLAG_MAYBE |
+                       DCERPC_PFC_FLAG_OBJECT_UUID);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("process_request_pdu: invalid pdu: %s\n",
+                         nt_errstr(status)));
+               NDR_PRINT_DEBUG(ncacn_packet, pkt);
+               set_incoming_fault(p);
+               return false;
+       }
+
        hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
        if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
                p->header2 = hdr2;