From: Stefan Metzmacher Date: Sat, 27 Jun 2015 08:31:48 +0000 (+0200) Subject: CVE-2015-5370: s4:librpc/rpc: use dcerpc_verify_ncacn_packet_header() to verify BIND_... X-Git-Tag: samba-4.2.10~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e88acf1cef2c60217f0d0365c462a17ad5bf3ee;p=thirdparty%2Fsamba.git CVE-2015-5370: s4:librpc/rpc: use dcerpc_verify_ncacn_packet_header() to verify BIND_ACK,ALTER_RESP,RESPONSE pdus BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index f81d558e0a1..3a6dc571e19 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -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;