From 4a496d3b22bcb79a1458a7cc7d0b3d995338c237 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 21:23:14 +0100 Subject: [PATCH] CVE-2015-5370: s3:rpc_client: disconnect connection on protocol errors MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 67 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 00ff5303557..97f49446312 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -936,6 +936,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt = talloc(state, struct ncacn_packet); if (!state->pkt) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -945,6 +951,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt, !state->endianess); if (!NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, status); return; } @@ -962,6 +974,28 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) (unsigned)state->reply_pdu_offset, nt_errstr(status))); + if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; @@ -986,12 +1020,24 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) "%s\n", state->endianess?"little":"big", state->pkt->drep[0]?"little":"big")); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } @@ -999,6 +1045,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { if (!data_blob_realloc(NULL, &state->reply_pdu, state->reply_pdu_offset + rdata.length)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1027,6 +1079,14 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) subreq = get_complete_frag_send(state, state->ev, state->cli, &state->incoming_frag); + if (subreq == NULL) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (tevent_req_nomem(subreq, req)) { return; } @@ -2275,8 +2335,9 @@ static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx, /* * TODO: do a real async disconnect ... * - * For now the caller needs to free rpc_cli + * For now we do it sync... */ + TALLOC_FREE(hs->rpc_cli->transport); hs->rpc_cli = NULL; tevent_req_done(req); -- 2.11.4.GIT