diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-06-27 10:31:48 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2016-04-12 19:25:29 +0200 |
commit | 3bf476345f47b4f29e995e9879cc8876d639a316 (patch) | |
tree | b5889985cdc9d1274014fe05c0664bc5fd3239ea /source4/librpc/rpc | |
parent | 9f4d962206d09d92c99fe349c95abca9955737b5 (diff) | |
download | samba-3bf476345f47b4f29e995e9879cc8876d639a316.tar.gz |
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 <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 063ac34ea8e..567b4dc3116 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -743,6 +743,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: @@ -1344,8 +1353,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; @@ -2367,25 +2388,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; |