]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2015-5370: s4:librpc/rpc: use dcerpc_verify_ncacn_packet_header() to verify BIND_...
authorStefan Metzmacher <metze@samba.org>
Sat, 27 Jun 2015 08:31:48 +0000 (10:31 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 30 Mar 2016 02:10:07 +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>
source4/librpc/rpc/dcerpc.c

index f81d558e0a1cf781e82bd132ed099aa1f787cc9a..3a6dc571e19cf877cf358ac82b3180b23cd38b38 100644 (file)
@@ -741,6 +741,15 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX
        struct dcerpc_auth auth;
        uint32_t auth_length;
 
+       status = dcerpc_verify_ncacn_packet_header(pkt, DCERPC_PKT_RESPONSE,
+                                       pkt->u.response.stub_and_verifier.length,
+                                       0, /* required_flags */
+                                       DCERPC_PFC_FLAG_FIRST |
+                                       DCERPC_PFC_FLAG_LAST);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        switch (c->security_state.auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
        case DCERPC_AUTH_LEVEL_INTEGRITY:
@@ -1342,8 +1351,20 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq,
                return;
        }
 
-       if ((pkt->ptype != DCERPC_PKT_BIND_ACK) ||
-           (pkt->u.bind_ack.num_results == 0)) {
+       status = dcerpc_verify_ncacn_packet_header(pkt,
+                                       DCERPC_PKT_BIND_ACK,
+                                       pkt->u.bind_ack.auth_info.length,
+                                       DCERPC_PFC_FLAG_FIRST |
+                                       DCERPC_PFC_FLAG_LAST,
+                                       DCERPC_PFC_FLAG_CONC_MPX |
+                                       DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
+       if (!NT_STATUS_IS_OK(status)) {
+               state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
+               tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
+               return;
+       }
+
+       if (pkt->u.bind_ack.num_results != 1) {
                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
                return;
@@ -2365,25 +2386,34 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq,
                return;
        }
 
-       if (pkt->ptype == DCERPC_PKT_ALTER_RESP &&
-           pkt->u.alter_resp.num_results == 1 &&
-           pkt->u.alter_resp.ctx_list[0].result != 0) {
-               status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]);
-               DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n",
-                        pkt->u.alter_resp.ctx_list[0].reason.value,
-                        nt_errstr(status)));
-               tevent_req_nterror(req, status);
+       status = dcerpc_verify_ncacn_packet_header(pkt,
+                                       DCERPC_PKT_ALTER_RESP,
+                                       pkt->u.alter_resp.auth_info.length,
+                                       DCERPC_PFC_FLAG_FIRST |
+                                       DCERPC_PFC_FLAG_LAST,
+                                       DCERPC_PFC_FLAG_CONC_MPX |
+                                       DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
+       if (!NT_STATUS_IS_OK(status)) {
+               state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
+               tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
                return;
        }
 
-       if (pkt->ptype != DCERPC_PKT_ALTER_RESP ||
-           pkt->u.alter_resp.num_results == 0 ||
-           pkt->u.alter_resp.ctx_list[0].result != 0) {
+       if (pkt->u.alter_resp.num_results != 1) {
                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
                return;
        }
 
+       if (pkt->u.alter_resp.ctx_list[0].result != 0) {
+               status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]);
+               DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n",
+                        pkt->u.alter_resp.ctx_list[0].reason.value,
+                        nt_errstr(status)));
+               tevent_req_nterror(req, status);
+               return;
+       }
+
        /* the alter_resp might contain a reply set of credentials */
        if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) {
                uint32_t auth_length;