summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-06-27 10:31:48 +0200
committerStefan Metzmacher <metze@samba.org>2016-04-12 19:25:29 +0200
commit3bf476345f47b4f29e995e9879cc8876d639a316 (patch)
treeb5889985cdc9d1274014fe05c0664bc5fd3239ea /source4/librpc/rpc
parent9f4d962206d09d92c99fe349c95abca9955737b5 (diff)
downloadsamba-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.c56
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;