Revision: 25660 http://sourceforge.net/p/gar/code/25660 Author: lblume Date: 2016-04-15 15:13:22 +0000 (Fri, 15 Apr 2016) Log Message: ----------- samba/branches/samba3: Add patches for recent CVEs
Modified Paths: -------------- csw/mgar/pkg/samba/branches/samba3/Makefile Added Paths: ----------- csw/mgar/pkg/samba/branches/samba3/files/CVE-2015-5370-v3-6.patch csw/mgar/pkg/samba/branches/samba3/files/CVE-2016-2110-v3-6.patch csw/mgar/pkg/samba/branches/samba3/files/CVE-2016-2111-v3-6.patch csw/mgar/pkg/samba/branches/samba3/files/CVE-2016-2112-v3-6.patch csw/mgar/pkg/samba/branches/samba3/files/CVE-2016-2115-v3-6.patch csw/mgar/pkg/samba/branches/samba3/files/CVE-2016-2118-v3-6.patch csw/mgar/pkg/samba/branches/samba3/files/CVE-preparation-v3-6.patch csw/mgar/pkg/samba/branches/samba3/files/samba-3.6.25-security-2015-12-16.patch Modified: csw/mgar/pkg/samba/branches/samba3/Makefile =================================================================== --- csw/mgar/pkg/samba/branches/samba3/Makefile 2016-04-15 13:55:00 UTC (rev 25659) +++ csw/mgar/pkg/samba/branches/samba3/Makefile 2016-04-15 15:13:22 UTC (rev 25660) @@ -30,6 +30,16 @@ PATCHFILES += 0002-smbd-patch-for-setgroups.c.patch PATCHFILES += 0003-rename-nss-modules.patch +# Upstream patches for recent CVEs +PATCHFILES += samba-3.6.25-security-2015-12-16.patch +PATCHFILES += CVE-preparation-v3-6.patch +PATCHFILES += CVE-2016-2118-v3-6.patch +PATCHFILES += CVE-2016-2115-v3-6.patch +PATCHFILES += CVE-2016-2112-v3-6.patch +PATCHFILES += CVE-2016-2111-v3-6.patch +PATCHFILES += CVE-2016-2110-v3-6.patch +PATCHFILES += CVE-2015-5370-v3-6.patch + BUILD_DEP_PKGS += CSWlibtalloc-dev BUILD_DEP_PKGS += CSWopenldap-dev BUILD_DEP_PKGS += CSWlibkrb5-dev @@ -418,8 +428,8 @@ # Studio 12 is the last supported on Solaris 9 GARCOMPILER_5.9 = SOS12 -GARCOMPILER_5.10 = SOS12U3 -GARCOMPILER_5.11 = SOS12U3 +GARCOMPILER_5.10 = GCC5 +GARCOMPILER_5.11 = GCC5 GARCOMPILER = $(GARCOMPILER_$(GAROSREL)) # Set the target dir for modules with the proper arch Added: csw/mgar/pkg/samba/branches/samba3/files/CVE-2015-5370-v3-6.patch =================================================================== --- csw/mgar/pkg/samba/branches/samba3/files/CVE-2015-5370-v3-6.patch (rev 0) +++ csw/mgar/pkg/samba/branches/samba3/files/CVE-2015-5370-v3-6.patch 2016-04-15 15:13:22 UTC (rev 25660) @@ -0,0 +1,3080 @@ +From 8716bb5e03cc4f10e2d4edc704d8defe7e8045f1 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Thu, 16 Jul 2015 22:46:05 +0200 +Subject: [PATCH 01/40] CVE-2015-5370: dcerpc.idl: add + DCERPC_{NCACN_PAYLOAD,FRAG}_MAX_SIZE defines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +--- + librpc/idl/dcerpc.idl | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl +index 75ef2ec..bbb42d1 100644 +--- a/librpc/idl/dcerpc.idl ++++ b/librpc/idl/dcerpc.idl +@@ -475,9 +475,11 @@ interface dcerpc + const uint8 DCERPC_PFC_OFFSET = 3; + const uint8 DCERPC_DREP_OFFSET = 4; + const uint8 DCERPC_FRAG_LEN_OFFSET = 8; ++ const uint32 DCERPC_FRAG_MAX_SIZE = 5840; + const uint8 DCERPC_AUTH_LEN_OFFSET = 10; + const uint8 DCERPC_CALL_ID_OFFSET = 12; + const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16; ++ const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */ + + /* little-endian flag */ + const uint8 DCERPC_DREP_LE = 0x10; +-- +2.8.1 + + +From 3b1cdbd2dc1c4d3773b4a1ef86ad1643abc5c208 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Sun, 28 Jun 2015 01:19:57 +0200 +Subject: [PATCH 02/40] CVE-2015-5370: librpc/rpc: simplify and harden + dcerpc_pull_auth_trailer() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +--- + librpc/rpc/dcerpc_util.c | 63 ++++++++++++++++++++++++++++++++++++------------ + librpc/rpc/rpc_common.h | 4 +-- + 2 files changed, 49 insertions(+), 18 deletions(-) + +diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c +index 97ef798..f936ef4 100644 +--- a/librpc/rpc/dcerpc_util.c ++++ b/librpc/rpc/dcerpc_util.c +@@ -92,31 +92,44 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob) + * + * @return - A NTSTATUS error code. + */ +-NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, ++NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, + TALLOC_CTX *mem_ctx, +- DATA_BLOB *pkt_trailer, ++ const DATA_BLOB *pkt_trailer, + struct dcerpc_auth *auth, +- uint32_t *auth_length, ++ uint32_t *_auth_length, + bool auth_data_only) + { + struct ndr_pull *ndr; + enum ndr_err_code ndr_err; +- uint32_t data_and_pad; ++ uint16_t data_and_pad; ++ uint16_t auth_length; ++ uint32_t tmp_length; + +- data_and_pad = pkt_trailer->length +- - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length); ++ ZERO_STRUCTP(auth); ++ if (_auth_length != NULL) { ++ *_auth_length = 0; ++ } + +- /* paranoia check for pad size. This would be caught anyway by +- the ndr_pull_advance() a few lines down, but it scared +- Jeremy enough for him to call me, so we might as well check +- it now, just to prevent someone posting a bogus YouTube +- video in the future. +- */ +- if (data_and_pad > pkt_trailer->length) { +- return NT_STATUS_INFO_LENGTH_MISMATCH; ++ /* Paranoia checks for auth_length. The caller should check this... */ ++ if (pkt->auth_length > pkt->frag_length) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ tmp_length = DCERPC_NCACN_PAYLOAD_OFFSET; ++ tmp_length += DCERPC_AUTH_TRAILER_LENGTH; ++ tmp_length += pkt->auth_length; ++ if (tmp_length > pkt->frag_length) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ if (pkt_trailer->length > UINT16_MAX) { ++ return NT_STATUS_INTERNAL_ERROR; + } + +- *auth_length = pkt_trailer->length - data_and_pad; ++ auth_length = DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length; ++ if (pkt_trailer->length < auth_length) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ ++ data_and_pad = pkt_trailer->length - auth_length; + + ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx); + if (!ndr) { +@@ -136,14 +149,28 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, + ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(ndr); ++ ZERO_STRUCTP(auth); + return ndr_map_error2ntstatus(ndr_err); + } + ++ if (data_and_pad < auth->auth_pad_length) { ++ DEBUG(1, (__location__ ": ERROR: pad length mismatch. " ++ "Calculated %u got %u\n", ++ (unsigned)data_and_pad, ++ (unsigned)auth->auth_pad_length)); ++ talloc_free(ndr); ++ ZERO_STRUCTP(auth); ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ + if (auth_data_only && data_and_pad != auth->auth_pad_length) { +- DEBUG(1, (__location__ ": WARNING: pad length mismatch. " ++ DEBUG(1, (__location__ ": ERROR: pad length mismatch. " + "Calculated %u got %u\n", + (unsigned)data_and_pad, + (unsigned)auth->auth_pad_length)); ++ talloc_free(ndr); ++ ZERO_STRUCTP(auth); ++ return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + DEBUG(6,(__location__ ": auth_pad_length %u\n", +@@ -152,6 +179,10 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, + talloc_steal(mem_ctx, auth->credentials.data); + talloc_free(ndr); + ++ if (_auth_length != NULL) { ++ *_auth_length = auth_length; ++ } ++ + return NT_STATUS_OK; + } + +diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h +index fe8129d..98a2e95 100644 +--- a/librpc/rpc/rpc_common.h ++++ b/librpc/rpc/rpc_common.h +@@ -158,9 +158,9 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob); + * + * @return - A NTSTATUS error code. + */ +-NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, ++NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, + TALLOC_CTX *mem_ctx, +- DATA_BLOB *pkt_trailer, ++ const DATA_BLOB *pkt_trailer, + struct dcerpc_auth *auth, + uint32_t *auth_length, + bool auth_data_only); +-- +2.8.1 + + +From 3aa9e6ec1cf2b2220968c3e0f711dfeca9ee3450 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Mon, 29 Jun 2015 10:24:45 +0200 +Subject: [PATCH 03/40] CVE-2015-5370: s3:librpc/rpc: don't call + dcerpc_pull_auth_trailer() if auth_length is 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All other paranoia checks are done within dcerpc_pull_auth_trailer() +now. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +--- + source3/librpc/rpc/dcerpc_helpers.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c +index 24f2f52..76f2acc 100644 +--- a/source3/librpc/rpc/dcerpc_helpers.c ++++ b/source3/librpc/rpc/dcerpc_helpers.c +@@ -899,16 +899,8 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + return NT_STATUS_INVALID_PARAMETER; + } + +- /* Paranioa checks for auth_length. */ +- if (pkt->auth_length > pkt->frag_length) { +- return NT_STATUS_INFO_LENGTH_MISMATCH; +- } +- if (((unsigned int)pkt->auth_length +- + DCERPC_AUTH_TRAILER_LENGTH < (unsigned int)pkt->auth_length) || +- ((unsigned int)pkt->auth_length +- + DCERPC_AUTH_TRAILER_LENGTH < DCERPC_AUTH_TRAILER_LENGTH)) { +- /* Integer wrap attempt. */ +- return NT_STATUS_INFO_LENGTH_MISMATCH; ++ if (pkt->auth_length == 0) { ++ return NT_STATUS_INVALID_PARAMETER; + } + + status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer, +-- +2.8.1 + + +From de179f2907134e2bc23d1e5cf9ac85a0c759dad3 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Fri, 26 Jun 2015 08:10:46 +0200 +Subject: [PATCH 04/40] CVE-2015-5370: librpc/rpc: add a + dcerpc_verify_ncacn_packet_header() helper function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 8266be48f455a5e541d0f7f62a1c8c38e0835976) +--- + librpc/rpc/dcerpc_util.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ + librpc/rpc/rpc_common.h | 5 ++++ + 2 files changed, 78 insertions(+) + +diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c +index f936ef4..2f599d5 100644 +--- a/librpc/rpc/dcerpc_util.c ++++ b/librpc/rpc/dcerpc_util.c +@@ -186,6 +186,79 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, + return NT_STATUS_OK; + } + ++/** ++* @brief Verify the fields in ncacn_packet header. ++* ++* @param pkt - The ncacn_packet strcuture ++* @param ptype - The expected PDU type ++* @param max_auth_info - The maximum size of a possible auth trailer ++* @param required_flags - The required flags for the pdu. ++* @param optional_flags - The possible optional flags for the pdu. ++* ++* @return - A NTSTATUS error code. ++*/ ++NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, ++ enum dcerpc_pkt_type ptype, ++ size_t max_auth_info, ++ uint8_t required_flags, ++ uint8_t optional_flags) ++{ ++ if (pkt->rpc_vers != 5) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ ++ if (pkt->rpc_vers_minor != 0) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ ++ if (pkt->auth_length > pkt->frag_length) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ ++ if (pkt->ptype != ptype) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ ++ if (max_auth_info > UINT16_MAX) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++ if (pkt->auth_length > 0) { ++ size_t max_auth_length; ++ ++ if (max_auth_info <= DCERPC_AUTH_TRAILER_LENGTH) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ max_auth_length = max_auth_info - DCERPC_AUTH_TRAILER_LENGTH; ++ ++ if (pkt->auth_length > max_auth_length) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ } ++ ++ if ((pkt->pfc_flags & required_flags) != required_flags) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ if (pkt->pfc_flags & ~(optional_flags|required_flags)) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ ++ if (pkt->drep[0] & ~DCERPC_DREP_LE) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ if (pkt->drep[1] != 0) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ if (pkt->drep[2] != 0) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ if (pkt->drep[3] != 0) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ ++ return NT_STATUS_OK; ++} ++ + struct dcerpc_read_ncacn_packet_state { + #if 0 + struct { +diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h +index 98a2e95..b3ae5b2 100644 +--- a/librpc/rpc/rpc_common.h ++++ b/librpc/rpc/rpc_common.h +@@ -164,6 +164,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, + struct dcerpc_auth *auth, + uint32_t *auth_length, + bool auth_data_only); ++NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, ++ enum dcerpc_pkt_type ptype, ++ size_t max_auth_info, ++ uint8_t required_flags, ++ uint8_t optional_flags); + struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tstream_context *stream); +-- +2.8.1 + + +From 4fda096df6005abdb964032bd4017da6496c1b50 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 05/40] CVE-2015-5370: s3:rpc_client: move AS/U hack to the top + of cli_pipe_validate_current_pdu() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 665b874b6022bfcdec3f13a9f5a844e5d1784aba) +--- + source3/rpc_client/cli_pipe.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 5ddabb7..295b88f 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -414,6 +414,19 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + */ + *rdata = *pdu; + ++ if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && ++ !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { ++ /* ++ * TODO: do we still need this hack which was introduced ++ * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0. ++ * ++ * I don't even know what AS/U might be... ++ */ ++ DEBUG(5, (__location__ ": bug in server (AS/U?), setting " ++ "fragment first/last ON.\n")); ++ pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; ++ } ++ + /* Ensure we have the correct type. */ + switch (pkt->ptype) { + case DCERPC_PKT_ALTER_RESP: +@@ -518,17 +531,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + +- /* Do this just before return - we don't want to modify any rpc header +- data before now as we may have needed to do cryptographic actions on +- it before. */ +- +- if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && +- !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { +- DEBUG(5, (__location__ ": bug in server (AS/U?), setting " +- "fragment first/last ON.\n")); +- pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; +- } +- + return NT_STATUS_OK; + } + +-- +2.8.1 + + +From e0d9dfcb27d6d76f819c32db4c1f3dd720f7c964 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 06/40] CVE-2015-5370: s3:rpc_client: remove useless + frag_length check in rpc_api_pipe_got_pdu() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +dcerpc_pull_ncacn_packet() already verifies this. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 9a3f045244b12ff9f77d2664396137c390042297) +--- + source3/rpc_client/cli_pipe.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 295b88f..2787fbc 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -898,14 +898,6 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) + return; + } + +- if (state->incoming_frag.length != state->pkt->frag_length) { +- DEBUG(5, ("Incorrect pdu length %u, expected %u\n", +- (unsigned int)state->incoming_frag.length, +- (unsigned int)state->pkt->frag_length)); +- tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); +- return; +- } +- + status = cli_pipe_validate_current_pdu(state, + state->cli, state->pkt, + &state->incoming_frag, +-- +2.8.1 + + +From 39c53a768b5b4eac7a644d4bd1afeb1cd7fb8ef1 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Fri, 26 Jun 2015 08:10:46 +0200 +Subject: [PATCH 07/40] CVE-2015-5370: s4:rpc_server: no authentication is + indicated by pkt->auth_length == 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +pkt->u.*.auth_info.length is not the correct thing to check. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(packported from commit c0236de09e542dbb168969d8ae9f0c150a75198e) +--- + source4/rpc_server/dcesrv_auth.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c +index 1e6aa24..61f2176 100644 +--- a/source4/rpc_server/dcesrv_auth.c ++++ b/source4/rpc_server/dcesrv_auth.c +@@ -46,7 +46,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) + NTSTATUS status; + uint32_t auth_length; + +- if (pkt->u.bind.auth_info.length == 0) { ++ if (pkt->auth_length == 0) { + dce_conn->auth_state.auth_info = NULL; + return true; + } +@@ -108,7 +108,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe + struct dcesrv_connection *dce_conn = call->conn; + NTSTATUS status; + +- if (!call->conn->auth_state.gensec_security) { ++ if (call->pkt.auth_length == 0) { + return NT_STATUS_OK; + } + +@@ -155,10 +155,16 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) + NTSTATUS status; + uint32_t auth_length; + +- /* We can't work without an existing gensec state, and an new blob to feed it */ +- if (!dce_conn->auth_state.auth_info || +- !dce_conn->auth_state.gensec_security || +- pkt->u.auth3.auth_info.length == 0) { ++ if (pkt->auth_length == 0) { ++ return false; ++ } ++ ++ if (!dce_conn->auth_state.auth_info) { ++ return false; ++ } ++ ++ /* We can't work without an existing gensec state */ ++ if (!dce_conn->auth_state.gensec_security) { + return false; + } + +@@ -203,7 +209,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) + uint32_t auth_length; + + /* on a pure interface change there is no auth blob */ +- if (pkt->u.alter.auth_info.length == 0) { ++ if (pkt->auth_length == 0) { + return true; + } + +@@ -238,8 +244,7 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack + + /* on a pure interface change there is no auth_info structure + setup */ +- if (!call->conn->auth_state.auth_info || +- dce_conn->auth_state.auth_info->credentials.length == 0) { ++ if (call->pkt.auth_length == 0) { + return NT_STATUS_OK; + } + +-- +2.8.1 + + +From f37e77ea11f691fe0717797890c0ac2d4fc76792 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Sat, 27 Jun 2015 10:31:48 +0200 +Subject: [PATCH 08/40] CVE-2015-5370: s4:librpc/rpc: check pkt->auth_length + before calling dcerpc_pull_auth_trailer + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Ralph Boehme <s...@samba.org> +(backported from 630dcb55ad7a3a89bcd8643c98a5cdbfb8735ef7) +--- + source4/librpc/rpc/dcerpc.c | 13 ++++++++++--- + source4/rpc_server/dcesrv_auth.c | 5 +++++ + 2 files changed, 15 insertions(+), 3 deletions(-) + +diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c +index 742d710..cfbccd6 100644 +--- a/source4/librpc/rpc/dcerpc.c ++++ b/source4/librpc/rpc/dcerpc.c +@@ -701,6 +701,14 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX + return NT_STATUS_INVALID_LEVEL; + } + ++ if (pkt->auth_length == 0) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; ++ } ++ ++ if (c->security_state.generic_state == NULL) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ + status = dcerpc_pull_auth_trailer(pkt, mem_ctx, + &pkt->u.response.stub_and_verifier, + &auth, &auth_length, false); +@@ -1074,7 +1082,7 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req, + } + + /* the bind_ack might contain a reply set of credentials */ +- if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) { ++ if (conn->security_state.auth_info && pkt->auth_length) { + NTSTATUS status; + uint32_t auth_length; + status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.bind_ack.auth_info, +@@ -1847,8 +1855,7 @@ static void dcerpc_alter_recv_handler(struct rpc_request *req, + } + + /* the alter_resp might contain a reply set of credentials */ +- if (recv_pipe->conn->security_state.auth_info && +- pkt->u.alter_resp.auth_info.length) { ++ if (recv_pipe->conn->security_state.auth_info && pkt->auth_length) { + struct dcecli_connection *conn = recv_pipe->conn; + NTSTATUS status; + uint32_t auth_length; +diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c +index 61f2176..3051c1c 100644 +--- a/source4/rpc_server/dcesrv_auth.c ++++ b/source4/rpc_server/dcesrv_auth.c +@@ -320,6 +320,11 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) + return false; + } + ++ if (pkt->auth_length == 0) { ++ DEBUG(1,("dcesrv_auth_request: unexpected auth_length of 0\n")); ++ return false; ++ } ++ + status = dcerpc_pull_auth_trailer(pkt, call, + &pkt->u.request.stub_and_verifier, + &auth, &auth_length, false); +-- +2.8.1 + + +From d3e41f6a15df3669b52009e48ce808b50bb837e4 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Sun, 28 Jun 2015 01:19:57 +0200 +Subject: [PATCH 09/40] CVE-2015-5370: librpc/rpc: don't allow pkt->auth_length + == 0 in dcerpc_pull_auth_trailer() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All callers should have already checked that. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 1ed83c7657a3b405db1928db06c29f41d2738186) +--- + librpc/rpc/dcerpc_util.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c +index 2f599d5..89b7597 100644 +--- a/librpc/rpc/dcerpc_util.c ++++ b/librpc/rpc/dcerpc_util.c +@@ -111,6 +111,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, + } + + /* Paranoia checks for auth_length. The caller should check this... */ ++ if (pkt->auth_length == 0) { ++ return NT_STATUS_INTERNAL_ERROR; ++ } ++ ++ /* Paranoia checks for auth_length. The caller should check this... */ + if (pkt->auth_length > pkt->frag_length) { + return NT_STATUS_INTERNAL_ERROR; + } +-- +2.8.1 + + +From fc994e4614d7ff43736ff2a516d42bb43b7c8ec9 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Thu, 9 Jul 2015 07:59:24 +0200 +Subject: [PATCH 10/40] CVE-2015-5370: s3:librpc/rpc: remove auth trailer and + possible padding within dcerpc_check_auth() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This simplifies the callers a lot. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit df3cdf072d1c1e6fd0a58e0374348758f5c65a49) +--- + source3/librpc/rpc/dcerpc.h | 5 ++--- + source3/librpc/rpc/dcerpc_helpers.c | 31 ++++++++++++++++++++----------- + source3/rpc_client/cli_pipe.c | 33 ++++++++++----------------------- + source3/rpc_server/srv_pipe.c | 17 +---------------- + 4 files changed, 33 insertions(+), 53 deletions(-) + +diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h +index d14d8e0..e7cca9e 100644 +--- a/source3/librpc/rpc/dcerpc.h ++++ b/source3/librpc/rpc/dcerpc.h +@@ -85,9 +85,8 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, + NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + struct ncacn_packet *pkt, + DATA_BLOB *pkt_trailer, +- size_t header_size, +- DATA_BLOB *raw_pkt, +- size_t *pad_len); ++ uint8_t header_size, ++ DATA_BLOB *raw_pkt); + + /* The following definitions come from librpc/rpc/rpc_common.c */ + +diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c +index 76f2acc..d871339 100644 +--- a/source3/librpc/rpc/dcerpc_helpers.c ++++ b/source3/librpc/rpc/dcerpc_helpers.c +@@ -844,19 +844,18 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, + * + * @param auth The auth data for the connection + * @param pkt The actual ncacn_packet +-* @param pkt_trailer The stub_and_verifier part of the packet ++* @param pkt_trailer [in][out] The stub_and_verifier part of the packet, ++* the auth_trailer and padding will be removed. + * @param header_size The header size + * @param raw_pkt The whole raw packet data blob +-* @param pad_len [out] The padding length used in the packet + * + * @return A NTSTATUS error code + */ + NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + struct ncacn_packet *pkt, + DATA_BLOB *pkt_trailer, +- size_t header_size, +- DATA_BLOB *raw_pkt, +- size_t *pad_len) ++ uint8_t header_size, ++ DATA_BLOB *raw_pkt) + { + struct schannel_state *schannel_auth; + struct auth_ntlmssp_state *ntlmssp_ctx; +@@ -868,6 +867,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + DATA_BLOB full_pkt; + DATA_BLOB data; + ++ /* ++ * These check should be done in the caller. ++ */ ++ SMB_ASSERT(raw_pkt->length == pkt->frag_length); ++ SMB_ASSERT(header_size <= pkt->frag_length); ++ SMB_ASSERT(pkt_trailer->length < pkt->frag_length); ++ SMB_ASSERT((pkt_trailer->length + header_size) <= pkt->frag_length); ++ + switch (auth->auth_level) { + case DCERPC_AUTH_LEVEL_PRIVACY: + DEBUG(10, ("Requested Privacy.\n")); +@@ -881,7 +888,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + if (pkt->auth_length != 0) { + break; + } +- *pad_len = 0; + return NT_STATUS_OK; + + case DCERPC_AUTH_LEVEL_NONE: +@@ -890,7 +896,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + "authenticated connection!\n")); + return NT_STATUS_INVALID_PARAMETER; + } +- *pad_len = 0; + return NT_STATUS_OK; + + default: +@@ -909,10 +914,11 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + return status; + } + ++ pkt_trailer->length -= auth_length; + data = data_blob_const(raw_pkt->data + header_size, +- pkt_trailer->length - auth_length); +- full_pkt = data_blob_const(raw_pkt->data, +- raw_pkt->length - auth_info.credentials.length); ++ pkt_trailer->length); ++ full_pkt = data_blob_const(raw_pkt->data, raw_pkt->length); ++ full_pkt.length -= auth_info.credentials.length; + + switch (auth->auth_type) { + case DCERPC_AUTH_TYPE_NONE: +@@ -988,10 +994,13 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + * pkt_trailer actually has a copy of the raw data, and they + * are still both used in later calls */ + if (auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { ++ if (pkt_trailer->length != data.length) { ++ return NT_STATUS_INVALID_PARAMETER; ++ } + memcpy(pkt_trailer->data, data.data, data.length); + } + +- *pad_len = auth_info.auth_pad_length; ++ pkt_trailer->length -= auth_info.auth_pad_length; + data_blob_free(&auth_info.credentials); + return NT_STATUS_OK; + } +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 2787fbc..776e2bf 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -404,9 +404,9 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + DATA_BLOB *rdata, + DATA_BLOB *reply_pdu) + { +- struct dcerpc_response *r; ++ const struct dcerpc_response *r = NULL; ++ DATA_BLOB tmp_stub = data_blob_null; + NTSTATUS ret = NT_STATUS_OK; +- size_t pad_len = 0; + + /* + * Point the return values at the real data including the RPC +@@ -440,37 +440,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + + r = &pkt->u.response; + ++ tmp_stub.data = r->stub_and_verifier.data; ++ tmp_stub.length = r->stub_and_verifier.length; ++ + /* Here's where we deal with incoming sign/seal. */ + ret = dcerpc_check_auth(cli->auth, pkt, +- &r->stub_and_verifier, ++ &tmp_stub, + DCERPC_RESPONSE_LENGTH, +- pdu, &pad_len); ++ pdu); + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } + +- if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) { +- return NT_STATUS_BUFFER_TOO_SMALL; +- } +- + /* Point the return values at the NDR data. */ +- rdata->data = r->stub_and_verifier.data; +- +- if (pkt->auth_length) { +- /* We've already done integer wrap tests in +- * dcerpc_check_auth(). */ +- rdata->length = r->stub_and_verifier.length +- - pad_len +- - DCERPC_AUTH_TRAILER_LENGTH +- - pkt->auth_length; +- } else { +- rdata->length = r->stub_and_verifier.length; +- } ++ *rdata = tmp_stub; + +- DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n", ++ DEBUG(10, ("Got pdu len %lu, data_len %lu\n", + (long unsigned int)pdu->length, +- (long unsigned int)rdata->length, +- (unsigned int)pad_len)); ++ (long unsigned int)rdata->length)); + + /* + * If this is the first reply, and the allocation hint is +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 964b843..0ab7dc6 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1848,7 +1848,6 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth, + { + NTSTATUS status; + size_t hdr_size = DCERPC_REQUEST_LENGTH; +- size_t pad_len; + + DEBUG(10, ("Checking request auth.\n")); + +@@ -1859,25 +1858,11 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth, + /* in case of sealing this function will unseal the data in place */ + status = dcerpc_check_auth(auth, pkt, + &pkt->u.request.stub_and_verifier, +- hdr_size, raw_pkt, +- &pad_len); ++ hdr_size, raw_pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + +- +- /* remove padding and auth trailer, +- * this way the caller will get just the data */ +- if (pkt->auth_length) { +- size_t trail_len = pad_len +- + DCERPC_AUTH_TRAILER_LENGTH +- + pkt->auth_length; +- if (pkt->u.request.stub_and_verifier.length < trail_len) { +- return NT_STATUS_INFO_LENGTH_MISMATCH; +- } +- pkt->u.request.stub_and_verifier.length -= trail_len; +- } +- + return NT_STATUS_OK; + } + +-- +2.8.1 + + +From 79bd5e74ad984a4f805e34bff5c4199da522c923 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Thu, 9 Jul 2015 07:59:24 +0200 +Subject: [PATCH 11/40] CVE-2015-5370: s3:librpc/rpc: let dcerpc_check_auth() + auth_{type,level} against the expected values. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 19f489d32c03ff5fafd34fe86a075d782af1989a) +--- + source3/librpc/rpc/dcerpc_helpers.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c +index d871339..c07835f 100644 +--- a/source3/librpc/rpc/dcerpc_helpers.c ++++ b/source3/librpc/rpc/dcerpc_helpers.c +@@ -914,6 +914,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + return status; + } + ++ if (auth_info.auth_type != auth->auth_type) { ++ return NT_STATUS_INVALID_PARAMETER; ++ } ++ ++ if (auth_info.auth_level != auth->auth_level) { ++ return NT_STATUS_INVALID_PARAMETER; ++ } ++ + pkt_trailer->length -= auth_length; + data = data_blob_const(raw_pkt->data + header_size, + pkt_trailer->length); +-- +2.8.1 + + +From acabcb860d2e77b5b8ef878696b4405599f8c761 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 12/40] CVE-2015-5370: s3:rpc_client: make use of + dcerpc_pull_auth_trailer() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The does much more validation than dcerpc_pull_dcerpc_auth(). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit acea87f158f02c3240abff45c3e54c7d5fa60b29) +--- + source3/rpc_client/cli_pipe.c | 20 ++++++-------------- + 1 file changed, 6 insertions(+), 14 deletions(-) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 776e2bf..27e37f8 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -1938,20 +1938,15 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) + rpc_pipe_bind_step_two_trigger(req); + return; + +- case DCERPC_AUTH_TYPE_NTLMSSP: +- case DCERPC_AUTH_TYPE_SPNEGO: +- case DCERPC_AUTH_TYPE_KRB5: +- /* Paranoid lenght checks */ +- if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH +- + pkt->auth_length) { +- tevent_req_nterror(req, +- NT_STATUS_INFO_LENGTH_MISMATCH); ++ default: ++ if (pkt->auth_length == 0) { ++ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + /* get auth credentials */ +- status = dcerpc_pull_dcerpc_auth(talloc_tos(), +- &pkt->u.bind_ack.auth_info, +- &auth, false); ++ status = dcerpc_pull_auth_trailer(pkt, talloc_tos(), ++ &pkt->u.bind_ack.auth_info, ++ &auth, NULL, true); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to pull dcerpc auth: %s.\n", + nt_errstr(status))); +@@ -1959,9 +1954,6 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) + return; + } + break; +- +- default: +- goto err_out; + } + + /* +-- +2.8.1 + + +From adf098f191acd3cb6ba2b8893b6c259af66d8696 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 13/40] CVE-2015-5370: s3:rpc_client: make use of + dcerpc_verify_ncacn_packet_header() in cli_pipe_validate_current_pdu() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 81bbffa14f5f6faa9801a3bf2d564d2762d49bb6) +--- + source3/rpc_client/cli_pipe.c | 111 ++++++++++++++++++++++++++++++++++++------ + 1 file changed, 96 insertions(+), 15 deletions(-) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 27e37f8..6a22d38 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -429,17 +429,89 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + + /* Ensure we have the correct type. */ + switch (pkt->ptype) { +- case DCERPC_PKT_ALTER_RESP: ++ case DCERPC_PKT_BIND_NAK: ++ DEBUG(1, (__location__ ": Bind NACK received from %s!\n", ++ rpccli_pipe_txt(talloc_tos(), cli))); ++ ++ ret = dcerpc_verify_ncacn_packet_header(pkt, ++ DCERPC_PKT_BIND_NAK, ++ 0, /* max_auth_info */ ++ DCERPC_PFC_FLAG_FIRST | ++ DCERPC_PFC_FLAG_LAST, ++ 0); /* optional flags */ ++ if (!NT_STATUS_IS_OK(ret)) { ++ DEBUG(1, (__location__ ": Connection to %s got an unexpected " ++ "RPC packet type - %u, expected %u: %s\n", ++ rpccli_pipe_txt(talloc_tos(), cli), ++ pkt->ptype, expected_pkt_type, ++ nt_errstr(ret))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ return ret; ++ } ++ ++ /* Use this for now... */ ++ return NT_STATUS_NETWORK_ACCESS_DENIED; ++ + case DCERPC_PKT_BIND_ACK: ++ ret = dcerpc_verify_ncacn_packet_header(pkt, ++ expected_pkt_type, ++ 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(ret)) { ++ DEBUG(1, (__location__ ": Connection to %s got an unexpected " ++ "RPC packet type - %u, expected %u: %s\n", ++ rpccli_pipe_txt(talloc_tos(), cli), ++ pkt->ptype, expected_pkt_type, ++ nt_errstr(ret))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ return ret; ++ } + +- /* Client code never receives this kind of packets */ + break; + ++ case DCERPC_PKT_ALTER_RESP: ++ ret = dcerpc_verify_ncacn_packet_header(pkt, ++ expected_pkt_type, ++ 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(ret)) { ++ DEBUG(1, (__location__ ": Connection to %s got an unexpected " ++ "RPC packet type - %u, expected %u: %s\n", ++ rpccli_pipe_txt(talloc_tos(), cli), ++ pkt->ptype, expected_pkt_type, ++ nt_errstr(ret))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ return ret; ++ } ++ ++ break; + + case DCERPC_PKT_RESPONSE: + + r = &pkt->u.response; + ++ ret = dcerpc_verify_ncacn_packet_header(pkt, ++ expected_pkt_type, ++ r->stub_and_verifier.length, ++ 0, /* required_flags */ ++ DCERPC_PFC_FLAG_FIRST | ++ DCERPC_PFC_FLAG_LAST); ++ if (!NT_STATUS_IS_OK(ret)) { ++ DEBUG(1, (__location__ ": Connection to %s got an unexpected " ++ "RPC packet type - %u, expected %u: %s\n", ++ rpccli_pipe_txt(talloc_tos(), cli), ++ pkt->ptype, expected_pkt_type, ++ nt_errstr(ret))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ return ret; ++ } ++ + tmp_stub.data = r->stub_and_verifier.data; + tmp_stub.length = r->stub_and_verifier.length; + +@@ -449,6 +521,12 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + DCERPC_RESPONSE_LENGTH, + pdu); + if (!NT_STATUS_IS_OK(ret)) { ++ DEBUG(1, (__location__ ": Connection to %s got an unexpected " ++ "RPC packet type - %u, expected %u: %s\n", ++ rpccli_pipe_txt(talloc_tos(), cli), ++ pkt->ptype, expected_pkt_type, ++ nt_errstr(ret))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + +@@ -478,14 +556,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + + break; + +- case DCERPC_PKT_BIND_NAK: +- DEBUG(1, (__location__ ": Bind NACK received from %s!\n", +- rpccli_pipe_txt(talloc_tos(), cli))); +- /* Use this for now... */ +- return NT_STATUS_NETWORK_ACCESS_DENIED; +- + case DCERPC_PKT_FAULT: + ++ ret = dcerpc_verify_ncacn_packet_header(pkt, ++ DCERPC_PKT_FAULT, ++ 0, /* max_auth_info */ ++ DCERPC_PFC_FLAG_FIRST | ++ DCERPC_PFC_FLAG_LAST, ++ DCERPC_PFC_FLAG_DID_NOT_EXECUTE); ++ if (!NT_STATUS_IS_OK(ret)) { ++ DEBUG(1, (__location__ ": Connection to %s got an unexpected " ++ "RPC packet type - %u, expected %u: %s\n", ++ rpccli_pipe_txt(talloc_tos(), cli), ++ pkt->ptype, expected_pkt_type, ++ nt_errstr(ret))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ return ret; ++ } ++ + DEBUG(1, (__location__ ": RPC fault code %s received " + "from %s!\n", + dcerpc_errstr(talloc_tos(), +@@ -502,13 +590,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + +- if (pkt->ptype != expected_pkt_type) { +- DEBUG(3, (__location__ ": Connection to %s got an unexpected " +- "RPC packet type - %u, not %u\n", +- rpccli_pipe_txt(talloc_tos(), cli), +- pkt->ptype, expected_pkt_type)); +- return NT_STATUS_RPC_PROTOCOL_ERROR; +- } + + if (pkt->call_id != call_id) { + DEBUG(3, (__location__ ": Connection to %s got an unexpected " +-- +2.8.1 + + +From 46c9eb371fda87c5b0c5ba30e95c4f4992c9dd00 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Fri, 10 Jul 2015 14:48:38 +0200 +Subject: [PATCH 14/40] CVE-2015-5370: s3:rpc_client: protect + rpc_api_pipe_got_pdu() against too large payloads +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 98182969e761429e577064e1a0fd5cbc6b50d7d9) +--- + source3/rpc_client/cli_pipe.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 6a22d38..755b458 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -1007,6 +1007,11 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) + return; + } + ++ if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { ++ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); ++ return; ++ } ++ + /* Now copy the data portion out of the pdu into rbuf. */ + if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { + if (!data_blob_realloc(NULL, &state->reply_pdu, +-- +2.8.1 + + +From e7866caecb0433d490172f3b262280a7d6902c4d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 22:51:18 +0200 +Subject: [PATCH 15/40] CVE-2015-5370: s3:rpc_client: verify auth_{type,level} + in rpc_pipe_bind_step_one_done() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit df51c22bea7fbf906613ceb160f16f298b2e3106) +--- + source3/rpc_client/cli_pipe.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 755b458..1c4ff01 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -2039,6 +2039,21 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) + tevent_req_nterror(req, status); + return; + } ++ ++ if (auth.auth_type != pauth->auth_type) { ++ DEBUG(0, (__location__ " Auth type %u mismatch expected %u.\n", ++ auth.auth_type, pauth->auth_type)); ++ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); ++ return; ++ } ++ ++ if (auth.auth_level != pauth->auth_level) { ++ DEBUG(0, (__location__ " Auth level %u mismatch expected %u.\n", ++ auth.auth_level, pauth->auth_level)); ++ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); ++ return; ++ } ++ + break; + } + +-- +2.8.1 + + +From b73d83a791237fe0262b4dcca8adf16b457eb188 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 16/40] CVE-2015-5370: s3:rpc_server: make use of + dcerpc_pull_auth_trailer() in api_pipe_{bind_req,alter_context,bind_auth3}() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 2a92546590a78760d2fe0e63067a3888dbce53be) +--- + source3/rpc_server/srv_pipe.c | 62 +++++++++---------------------------------- + 1 file changed, 13 insertions(+), 49 deletions(-) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 0ab7dc6..40b1b8e 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1012,25 +1012,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + * Check if this is an authenticated bind request. + */ + if (pkt->auth_length) { +- /* Quick length check. Won't catch a bad auth footer, +- * prevents overrun. */ +- +- if (pkt->frag_length < RPC_HEADER_LEN + +- DCERPC_AUTH_TRAILER_LENGTH + +- pkt->auth_length) { +- DEBUG(0,("api_pipe_bind_req: auth_len (%u) " +- "too long for fragment %u.\n", +- (unsigned int)pkt->auth_length, +- (unsigned int)pkt->frag_length)); +- goto err_exit; +- } +- + /* + * Decode the authentication verifier. + */ +- status = dcerpc_pull_dcerpc_auth(pkt, +- &pkt->u.bind.auth_info, +- &auth_info, p->endian); ++ status = dcerpc_pull_auth_trailer(pkt, pkt, ++ &pkt->u.bind.auth_info, ++ &auth_info, NULL, true); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); + goto err_exit; +@@ -1233,23 +1220,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + goto err; + } + +- /* Ensure there's enough data for an authenticated request. */ +- if (pkt->frag_length < RPC_HEADER_LEN +- + DCERPC_AUTH_TRAILER_LENGTH +- + pkt->auth_length) { +- DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len " +- "%u is too large.\n", +- (unsigned int)pkt->auth_length)); +- goto err; +- } +- + /* + * Decode the authentication verifier response. + */ + +- status = dcerpc_pull_dcerpc_auth(pkt, +- &pkt->u.auth3.auth_info, +- &auth_info, p->endian); ++ status = dcerpc_pull_auth_trailer(pkt, pkt, ++ &pkt->u.auth3.auth_info, ++ &auth_info, NULL, true); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n")); + goto err; +@@ -1382,34 +1359,21 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + * Check if this is an authenticated alter context request. + */ + if (pkt->auth_length) { +- /* Quick length check. Won't catch a bad auth footer, +- * prevents overrun. */ +- +- if (pkt->frag_length < RPC_HEADER_LEN + +- DCERPC_AUTH_TRAILER_LENGTH + +- pkt->auth_length) { +- DEBUG(0,("api_pipe_alter_context: auth_len (%u) " +- "too long for fragment %u.\n", +- (unsigned int)pkt->auth_length, +- (unsigned int)pkt->frag_length )); ++ /* We can only finish if the pipe is unbound for now */ ++ if (p->pipe_bound) { ++ DEBUG(0, (__location__ ": Pipe already bound, " ++ "Altering Context not yet supported!\n")); + goto err_exit; + } + +- status = dcerpc_pull_dcerpc_auth(pkt, +- &pkt->u.bind.auth_info, +- &auth_info, p->endian); ++ status = dcerpc_pull_auth_trailer(pkt, pkt, ++ &pkt->u.bind.auth_info, ++ &auth_info, NULL, true); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); + goto err_exit; + } + +- /* We can only finish if the pipe is unbound for now */ +- if (p->pipe_bound) { +- DEBUG(0, (__location__ ": Pipe already bound, " +- "Altering Context not yet supported!\n")); +- goto err_exit; +- } +- + if (auth_info.auth_type != p->auth.auth_type) { + DEBUG(0, ("Auth type mismatch! Client sent %d, " + "but auth was started as type %d!\n", +-- +2.8.1 + + +From 06e5f78341fbe220bd9fb8e27a7f2f8f4e593fa6 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 23 Dec 2015 12:38:55 +0100 +Subject: [PATCH 17/40] CVE-2015-5370: s3:rpc_server: let a failing + sec_verification_trailer mark the connection as broken + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +(cherry picked from commit 189c0fbb7a3405f0893f23e5b8d755d259f98eaf) +--- + source3/rpc_server/srv_pipe.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 40b1b8e..da9b91c 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1663,6 +1663,7 @@ static bool api_pipe_request(struct pipes_struct *p, + + if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) { + DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n")); ++ set_incoming_fault(p); + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); + data_blob_free(&p->out_data.rdata); + TALLOC_FREE(frame); +-- +2.8.1 + + +From 38ff4f5913f5a323b635253748684f98fc63549c Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 18/40] CVE-2015-5370: s3:rpc_server: don't ignore failures of + dcerpc_push_ncacn_packet() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 25bf597124f217c55b5ca71a5ea9cb0ea83943e5) +--- + source3/rpc_server/srv_pipe.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index da9b91c..71b4665 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1152,6 +1152,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", + nt_errstr(status))); ++ goto err_exit; + } + + if (auth_resp.length) { +@@ -1469,6 +1470,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", + nt_errstr(status))); ++ goto err_exit; + } + + if (auth_resp.length) { +-- +2.8.1 + + +From c24152e5778bcdc1f252bbbeacb89af0c6f4f578 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 19/40] CVE-2015-5370: s3:rpc_server: don't allow auth3 if the + authentication was already finished +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 69280e6acef7c3941407d4308b659c5e90ed702d) +--- + source3/rpc_server/srv_pipe.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 71b4665..4e5b50d4 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1216,8 +1216,15 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + + DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__)); + ++ /* We can only finish if the pipe is unbound for now */ ++ if (p->pipe_bound) { ++ DEBUG(0, (__location__ ": Pipe already bound, " ++ "AUTH3 not supported!\n")); ++ goto err; ++ } ++ + if (pkt->auth_length == 0) { +- DEBUG(0, ("No auth field sent for bind request!\n")); ++ DEBUG(1, ("No auth field sent for auth3 request!\n")); + goto err; + } + +-- +2.8.1 + + +From 1156d7445ed3c86af2610f0bfd2ea38831010726 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 14 Jul 2015 16:18:45 +0200 +Subject: [PATCH 20/40] CVE-2015-5370: s3:rpc_server: let a failing auth3 mark + the authentication as invalid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 8c96ef7b4fbd925607b26d351b14ad9a95febd88) +--- + source3/rpc_server/srv_pipe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 4e5b50d4..d28ba8e 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1304,7 +1304,7 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + return true; + + err: +- ++ p->pipe_bound = false; + TALLOC_FREE(p->auth.auth_ctx); + return false; + } +-- +2.8.1 + + +From da145d9e8a4c1b5d507734b599563fdb0fff90a9 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 21/40] CVE-2015-5370: s3:rpc_server: make sure auth_level + isn't changed by alter_context or auth3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 63d21d2546a1064be73582a499ec15b0e11e2708) +--- + source3/rpc_server/srv_pipe.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index d28ba8e..1b81a4c 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1252,6 +1252,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + goto err; + } + ++ if (auth_info.auth_level != p->auth.auth_level) { ++ DEBUG(1, ("Auth level mismatch! Client sent %d, " ++ "but auth was started as level %d!\n", ++ auth_info.auth_level, p->auth.auth_level)); ++ goto err; ++ } ++ + switch (auth_info.auth_type) { + case DCERPC_AUTH_TYPE_NTLMSSP: + ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx, +@@ -1389,6 +1396,12 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + goto err_exit; + } + ++ if (auth_info.auth_level != p->auth.auth_level) { ++ DEBUG(0, ("Auth level mismatch! Client sent %d, " ++ "but auth was started as level %d!\n", ++ auth_info.auth_level, p->auth.auth_level)); ++ goto err_exit; ++ } + + switch (auth_info.auth_type) { + case DCERPC_AUTH_TYPE_SPNEGO: +-- +2.8.1 + + +From 7a313b254fda2b7577a60bfb9d07ccd9c745abdf Mon Sep 17 00:00:00 2001 +From: Jeremy Allison <j...@samba.org> +Date: Tue, 7 Jul 2015 09:15:39 +0200 +Subject: [PATCH 22/40] CVE-2015-5370: s3:rpc_server: ensure that the message + ordering doesn't violate the spec +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The first pdu is always a BIND. + +REQUEST pdus are only allowed once the authentication +is finished. + +A simple anonymous authentication is finished after the BIND. +Real authentication may need additional ALTER or AUTH3 exchanges. + +Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Jeremy Allison <j...@samba.org> +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 0239bfa562ee303c4ac204375b3c66ca287f6cb0) +--- + source3/include/ntdomain.h | 7 ++++++ + source3/rpc_server/rpc_ncacn_np.c | 1 + + source3/rpc_server/rpc_server.c | 1 + + source3/rpc_server/srv_pipe.c | 51 ++++++++++++++++++++++++++++++++++----- + 4 files changed, 54 insertions(+), 6 deletions(-) + +diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h +index 650f1d0..b3c5451 100644 +--- a/source3/include/ntdomain.h ++++ b/source3/include/ntdomain.h +@@ -139,6 +139,13 @@ struct pipes_struct { + bool pipe_bound; + + /* ++ * States we can be in. ++ */ ++ bool allow_alter; ++ bool allow_bind; ++ bool allow_auth3; ++ ++ /* + * Set the DCERPC_FAULT to return. + */ + +diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c +index efdee27..f2e9d10 100644 +--- a/source3/rpc_server/rpc_ncacn_np.c ++++ b/source3/rpc_server/rpc_ncacn_np.c +@@ -171,6 +171,7 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, + + p->syntax = *syntax; + p->transport = NCALRPC; ++ p->allow_bind = true; + + DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n", + get_pipe_name_from_syntax(talloc_tos(), syntax), pipes_open)); +diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c +index 8ec55bb..376d26a 100644 +--- a/source3/rpc_server/rpc_server.c ++++ b/source3/rpc_server/rpc_server.c +@@ -102,6 +102,7 @@ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx, + p->syntax = id; + p->transport = transport; + p->ncalrpc_as_system = ncalrpc_as_system; ++ p->allow_bind = true; + + p->mem_ctx = talloc_named(p, 0, "pipe %s %p", pipe_name, p); + if (!p->mem_ctx) { +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 1b81a4c..41111aa 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -279,6 +279,9 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt) + p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; + p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; + p->pipe_bound = False; ++ p->allow_bind = false; ++ p->allow_alter = false; ++ p->allow_auth3 = false; + + return True; + } +@@ -828,6 +831,11 @@ static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p) + void *mech_ctx; + NTSTATUS status; + ++ if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) { ++ p->pipe_bound = true; ++ return NT_STATUS_OK; ++ } ++ + switch (p->auth.auth_type) { + case DCERPC_AUTH_TYPE_NTLMSSP: + ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx, +@@ -919,13 +927,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + DATA_BLOB auth_resp = data_blob_null; + DATA_BLOB auth_blob = data_blob_null; + +- /* No rebinds on a bound pipe - use alter context. */ +- if (p->pipe_bound) { +- DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound " +- "pipe %s.\n", +- get_pipe_name_from_syntax(talloc_tos(), &p->syntax))); ++ if (!p->allow_bind) { ++ DEBUG(2,("Pipe not in allow bind state\n")); + return setup_bind_nak(p, pkt); + } ++ p->allow_bind = false; + + if (pkt->u.bind.num_contexts == 0) { + DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n")); +@@ -1192,6 +1198,22 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + p->out_data.current_pdu_sent = 0; + + TALLOC_FREE(auth_blob.data); ++ ++ if (bind_ack_ctx.result == 0) { ++ p->allow_alter = true; ++ p->allow_auth3 = true; ++ if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) { ++ status = pipe_auth_verify_final(p); ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(0, ("pipe_auth_verify_final failed: %s\n", ++ nt_errstr(status))); ++ goto err_exit; ++ } ++ } ++ } else { ++ goto err_exit; ++ } ++ + return True; + + err_exit: +@@ -1216,6 +1238,11 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + + DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__)); + ++ if (!p->allow_auth3) { ++ DEBUG(1, ("Pipe not in allow auth3 state.\n")); ++ goto err; ++ } ++ + /* We can only finish if the pipe is unbound for now */ + if (p->pipe_bound) { + DEBUG(0, (__location__ ": Pipe already bound, " +@@ -1312,6 +1339,10 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + + err: + p->pipe_bound = false; ++ p->allow_bind = false; ++ p->allow_alter = false; ++ p->allow_auth3 = false; ++ + TALLOC_FREE(p->auth.auth_ctx); + return false; + } +@@ -1338,6 +1369,11 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + + DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__)); + ++ if (!p->allow_alter) { ++ DEBUG(1, ("Pipe not in allow alter state.\n")); ++ goto err_exit; ++ } ++ + if (pkt->u.bind.assoc_group_id != 0) { + assoc_gid = pkt->u.bind.assoc_group_id; + } else { +@@ -1363,7 +1399,6 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + bind_ack_ctx.reason = 0; + bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; + } else { +- p->pipe_bound = False; + /* Rejection reason: abstract syntax not supported */ + bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; + bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX; +@@ -1826,6 +1861,10 @@ void set_incoming_fault(struct pipes_struct *p) + p->in_data.pdu.length = 0; + p->fault_state = DCERPC_FAULT_CANT_PERFORM; + ++ p->allow_alter = false; ++ p->allow_auth3 = false; ++ p->pipe_bound = false; ++ + DEBUG(10, ("Setting fault state\n")); + } + +-- +2.8.1 + + +From 23147db714d05d113ca06d327ab65087f3420998 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 16:06:59 +0200 +Subject: [PATCH 23/40] CVE-2015-5370: s3:rpc_server: use 'alter' instead of + 'bind' for variables in api_pipe_alter_context() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit cdefee174d2f8920323e9e62966df4f4ced49ed3) +--- + source3/rpc_server/srv_pipe.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 41111aa..382d94a 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1359,7 +1359,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + uint16 assoc_gid; + NTSTATUS status; + union dcerpc_payload u; +- struct dcerpc_ack_ctx bind_ack_ctx; ++ struct dcerpc_ack_ctx alter_ack_ctx; + DATA_BLOB auth_resp = data_blob_null; + DATA_BLOB auth_blob = data_blob_null; + int pad_len = 0; +@@ -1374,8 +1374,8 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + goto err_exit; + } + +- if (pkt->u.bind.assoc_group_id != 0) { +- assoc_gid = pkt->u.bind.assoc_group_id; ++ if (pkt->u.alter.assoc_group_id != 0) { ++ assoc_gid = pkt->u.alter.assoc_group_id; + } else { + assoc_gid = 0x53f0; + } +@@ -1385,24 +1385,24 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + */ + + /* If the requested abstract synt uuid doesn't match our client pipe, +- reject the bind_ack & set the transfer interface synt to all 0's, ++ reject the alter_ack & set the transfer interface synt to all 0's, + ver 0 (observed when NT5 attempts to bind to abstract interfaces + unknown to NT4) + Needed when adding entries to a DACL from NT5 - SK */ + + if (check_bind_req(p, +- &pkt->u.bind.ctx_list[0].abstract_syntax, +- &pkt->u.bind.ctx_list[0].transfer_syntaxes[0], +- pkt->u.bind.ctx_list[0].context_id)) { ++ &pkt->u.alter.ctx_list[0].abstract_syntax, ++ &pkt->u.alter.ctx_list[0].transfer_syntaxes[0], ++ pkt->u.alter.ctx_list[0].context_id)) { + +- bind_ack_ctx.result = 0; +- bind_ack_ctx.reason = 0; +- bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; ++ alter_ack_ctx.result = 0; ++ alter_ack_ctx.reason = 0; ++ alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0]; + } else { + /* Rejection reason: abstract syntax not supported */ +- bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; +- bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX; +- bind_ack_ctx.syntax = null_ndr_syntax_id; ++ alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; ++ alter_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX; ++ alter_ack_ctx.syntax = null_ndr_syntax_id; + } + + /* +@@ -1417,7 +1417,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + } + + status = dcerpc_pull_auth_trailer(pkt, pkt, +- &pkt->u.bind.auth_info, ++ &pkt->u.alter.auth_info, + &auth_info, NULL, true); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); +@@ -1503,7 +1503,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + u.alter_resp.secondary_address_size = 1; + + u.alter_resp.num_results = 1; +- u.alter_resp.ctx_list = &bind_ack_ctx; ++ u.alter_resp.ctx_list = &alter_ack_ctx; + + /* NOTE: We leave the auth_info empty so we can calculate the padding + * later and then append the auth_info --simo */ +@@ -1523,7 +1523,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + &u, + &p->out_data.frag); + if (!NT_STATUS_IS_OK(status)) { +- DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", ++ DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n", + nt_errstr(status))); + goto err_exit; + } +-- +2.8.1 + + +From bf96df45abbd32c90a561b8f444e510d4a34da0e Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 16:06:59 +0200 +Subject: [PATCH 24/40] CVE-2015-5370: s3:rpc_server: verify presentation + context arrays +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 1e6b4abac14840e4cee1afc5d4811b0f0277eade) +--- + source3/rpc_server/srv_pipe.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 382d94a..335af2a 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -934,7 +934,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + p->allow_bind = false; + + if (pkt->u.bind.num_contexts == 0) { +- DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n")); ++ DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n")); ++ goto err_exit; ++ } ++ ++ if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) { ++ DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n")); + goto err_exit; + } + +@@ -1374,6 +1379,16 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + goto err_exit; + } + ++ if (pkt->u.alter.num_contexts == 0) { ++ DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n")); ++ goto err_exit; ++ } ++ ++ if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) { ++ DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n")); ++ goto err_exit; ++ } ++ + if (pkt->u.alter.assoc_group_id != 0) { + assoc_gid = pkt->u.alter.assoc_group_id; + } else { +-- +2.8.1 + + +From 5d564f46ae2621f99c4450d21a198b432ca0cd30 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 16:06:59 +0200 +Subject: [PATCH 25/40] CVE-2015-5370: s3:rpc_server: make use of + dcerpc_verify_ncacn_packet_header() to verify incoming pdus +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit e39fdceb25fc75b6f8c77c097bf8dbd2f4286618) +--- + source3/rpc_server/srv_pipe.c | 81 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 81 insertions(+) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 335af2a..2f404b4 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -42,6 +42,7 @@ + #include "auth.h" + #include "ntdomain.h" + #include "rpc_server/srv_pipe.h" ++#include "../librpc/gen_ndr/ndr_dcerpc.h" + #include "../librpc/ndr/ndr_dcerpc.h" + #include "../librpc/gen_ndr/ndr_samr.h" + #include "../librpc/gen_ndr/ndr_lsa.h" +@@ -933,6 +934,25 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + } + p->allow_bind = false; + ++ status = dcerpc_verify_ncacn_packet_header(pkt, ++ DCERPC_PKT_BIND, ++ pkt->u.bind.auth_info.length, ++ 0, /* required flags */ ++ DCERPC_PFC_FLAG_FIRST | ++ DCERPC_PFC_FLAG_LAST | ++ DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | ++ 0x08 | /* this is not defined, but should be ignored */ ++ DCERPC_PFC_FLAG_CONC_MPX | ++ DCERPC_PFC_FLAG_DID_NOT_EXECUTE | ++ DCERPC_PFC_FLAG_MAYBE | ++ DCERPC_PFC_FLAG_OBJECT_UUID); ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n", ++ nt_errstr(status))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ goto err_exit; ++ } ++ + if (pkt->u.bind.num_contexts == 0) { + DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n")); + goto err_exit; +@@ -1248,6 +1268,25 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + goto err; + } + ++ status = dcerpc_verify_ncacn_packet_header(pkt, ++ DCERPC_PKT_AUTH3, ++ pkt->u.auth3.auth_info.length, ++ 0, /* required flags */ ++ DCERPC_PFC_FLAG_FIRST | ++ DCERPC_PFC_FLAG_LAST | ++ DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | ++ 0x08 | /* this is not defined, but should be ignored */ ++ DCERPC_PFC_FLAG_CONC_MPX | ++ DCERPC_PFC_FLAG_DID_NOT_EXECUTE | ++ DCERPC_PFC_FLAG_MAYBE | ++ DCERPC_PFC_FLAG_OBJECT_UUID); ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n", ++ nt_errstr(status))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ goto err; ++ } ++ + /* We can only finish if the pipe is unbound for now */ + if (p->pipe_bound) { + DEBUG(0, (__location__ ": Pipe already bound, " +@@ -1379,6 +1418,25 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + goto err_exit; + } + ++ status = dcerpc_verify_ncacn_packet_header(pkt, ++ DCERPC_PKT_ALTER, ++ pkt->u.alter.auth_info.length, ++ 0, /* required flags */ ++ DCERPC_PFC_FLAG_FIRST | ++ DCERPC_PFC_FLAG_LAST | ++ DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | ++ 0x08 | /* this is not defined, but should be ignored */ ++ DCERPC_PFC_FLAG_CONC_MPX | ++ DCERPC_PFC_FLAG_DID_NOT_EXECUTE | ++ DCERPC_PFC_FLAG_MAYBE | ++ DCERPC_PFC_FLAG_OBJECT_UUID); ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n", ++ nt_errstr(status))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ goto err_exit; ++ } ++ + if (pkt->u.alter.num_contexts == 0) { + DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n")); + goto err_exit; +@@ -1923,6 +1981,29 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt + return False; + } + ++ /* ++ * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL. ++ * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later. ++ */ ++ status = dcerpc_verify_ncacn_packet_header(pkt, ++ DCERPC_PKT_REQUEST, ++ pkt->u.request.stub_and_verifier.length, ++ 0, /* required_flags */ ++ DCERPC_PFC_FLAG_FIRST | ++ DCERPC_PFC_FLAG_LAST | ++ 0x08 | /* this is not defined, but should be ignored */ ++ DCERPC_PFC_FLAG_CONC_MPX | ++ DCERPC_PFC_FLAG_DID_NOT_EXECUTE | ++ DCERPC_PFC_FLAG_MAYBE | ++ DCERPC_PFC_FLAG_OBJECT_UUID); ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(1, ("process_request_pdu: invalid pdu: %s\n", ++ nt_errstr(status))); ++ NDR_PRINT_DEBUG(ncacn_packet, pkt); ++ set_incoming_fault(p); ++ return false; ++ } ++ + /* Store the opnum */ + p->opnum = pkt->u.request.opnum; + +-- +2.8.1 + + +From 5a53b46092399686d5c1ade79e15eb093b9d1842 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 23 Dec 2015 12:40:58 +0100 +Subject: [PATCH 26/40] CVE-2015-5370: s3:rpc_server: disconnect the connection + after a fatal FAULT pdu +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 664d7ace0e68b42d2de99583757e0a985647eb4b) +--- + source3/rpc_server/rpc_server.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c +index 376d26a..3ba83e0 100644 +--- a/source3/rpc_server/rpc_server.c ++++ b/source3/rpc_server/rpc_server.c +@@ -664,6 +664,12 @@ static void named_pipe_packet_done(struct tevent_req *subreq) + goto fail; + } + ++ if (npc->p->fault_state != 0) { ++ DEBUG(2, ("Disconnect after fault\n")); ++ sys_errno = EINVAL; ++ goto fail; ++ } ++ + /* clear out any data that may have been left around */ + npc->count = 0; + TALLOC_FREE(npc->iov); +@@ -1392,6 +1398,12 @@ static void dcerpc_ncacn_packet_done(struct tevent_req *subreq) + goto fail; + } + ++ if (ncacn_conn->p->fault_state != 0) { ++ DEBUG(2, ("Disconnect after fault\n")); ++ sys_errno = EINVAL; ++ goto fail; ++ } ++ + /* clear out any data that may have been left around */ + ncacn_conn->count = 0; + TALLOC_FREE(ncacn_conn->iov); +-- +2.8.1 + + +From a895ca55f14cbdb28b7327d3a1fdbf2b5397ad96 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 23 Dec 2015 12:38:55 +0100 +Subject: [PATCH 27/40] CVE-2015-5370: s3:rpc_server: let a failing BIND mark + the connection as broken +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 8d97085efd8782e48d0f1162e3f56756acb99472) +--- + source3/rpc_server/srv_pipe.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 2f404b4..6275190 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -276,6 +276,7 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt) + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_sent = 0; + ++ set_incoming_fault(p); + TALLOC_FREE(p->auth.auth_ctx); + p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; + p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; +-- +2.8.1 + + +From 1633842f3667442c3a5bdf683fc0dbb905755b11 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 23 Dec 2015 12:38:55 +0100 +Subject: [PATCH 28/40] CVE-2015-5370: s3:rpc_server: use + DCERPC_NCA_S_PROTO_ERROR FAULTs for protocol errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit d30363f08efb81b22055d4445977c96df3737adf) +--- + source3/rpc_server/srv_pipe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 6275190..3fb8855 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1933,7 +1933,7 @@ void set_incoming_fault(struct pipes_struct *p) + data_blob_free(&p->in_data.data); + p->in_data.pdu_needed_len = 0; + p->in_data.pdu.length = 0; +- p->fault_state = DCERPC_FAULT_CANT_PERFORM; ++ p->fault_state = DCERPC_NCA_S_PROTO_ERROR; + + p->allow_alter = false; + p->allow_auth3 = false; +@@ -2254,7 +2254,7 @@ done: + "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(), + &p->syntax))); + set_incoming_fault(p); +- setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); ++ setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR)); + TALLOC_FREE(pkt); + } else { + /* +-- +2.8.1 + + +From 62e058a6874f9ae3f1856cd9c3c52516ce350f95 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Sat, 11 Jul 2015 10:58:07 +0200 +Subject: [PATCH 29/40] CVE-2015-5370: s3:librpc/rpc: remove unused + dcerpc_pull_dcerpc_auth() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 02aef978ff8f16009a52c2d981d414d019bc8dd9) +--- + source3/librpc/rpc/dcerpc.h | 4 ---- + source3/librpc/rpc/dcerpc_helpers.c | 41 ------------------------------------- + 2 files changed, 45 deletions(-) + +diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h +index e7cca9e..9452e85 100644 +--- a/source3/librpc/rpc/dcerpc.h ++++ b/source3/librpc/rpc/dcerpc.h +@@ -71,10 +71,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, + uint32_t auth_context_id, + const DATA_BLOB *credentials, + DATA_BLOB *blob); +-NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, +- const DATA_BLOB *blob, +- struct dcerpc_auth *r, +- bool bigendian); + NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, + size_t header_len, size_t data_left, + size_t max_xmit_frag, size_t pad_alignment, +diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c +index c07835f..e4d0e3a 100644 +--- a/source3/librpc/rpc/dcerpc_helpers.c ++++ b/source3/librpc/rpc/dcerpc_helpers.c +@@ -210,47 +210,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, + } + + /** +-* @brief Decodes a dcerpc_auth blob +-* +-* @param mem_ctx The memory context on which to allocate the packet +-* elements +-* @param blob The blob of data to decode +-* @param r An empty dcerpc_auth structure, must not be NULL +-* +-* @return a NTSTATUS error code +-*/ +-NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, +- const DATA_BLOB *blob, +- struct dcerpc_auth *r, +- bool bigendian) +-{ +- enum ndr_err_code ndr_err; +- struct ndr_pull *ndr; +- +- ndr = ndr_pull_init_blob(blob, mem_ctx); +- if (!ndr) { +- return NT_STATUS_NO_MEMORY; +- } +- if (bigendian) { +- ndr->flags |= LIBNDR_FLAG_BIGENDIAN; +- } +- +- ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r); +- +- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +- talloc_free(ndr); +- return ndr_map_error2ntstatus(ndr_err); +- } +- talloc_free(ndr); +- +- if (DEBUGLEVEL >= 10) { +- NDR_PRINT_DEBUG(dcerpc_auth, r); +- } +- +- return NT_STATUS_OK; +-} +- +-/** + * @brief Calculate how much data we can in a packet, including calculating + * auth token and pad lengths. + * +-- +2.8.1 + + +From 34cbf85617810fb81ad27250ef6bab0efd13a5e7 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 30/40] CVE-2015-5370: s3:rpc_server: check the transfer syntax + in check_bind_req() first +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 9464684010461947fa98d8ee084069e9cf362625) +--- + source3/rpc_server/srv_pipe.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 3fb8855..0e6b073 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -351,16 +351,24 @@ static bool check_bind_req(struct pipes_struct *p, + DEBUG(3,("check_bind_req for %s\n", + get_pipe_name_from_syntax(talloc_tos(), abstract))); + ++ ok = ndr_syntax_id_equal(transfer, &ndr_transfer_syntax); ++ if (!ok) { ++ DEBUG(1,("check_bind_req unknown transfer syntax for " ++ "%s context_id=%u\n", ++ get_pipe_name_from_syntax(talloc_tos(), abstract), ++ (unsigned)context_id)); ++ return false; ++ } ++ + /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ +- if (rpc_srv_pipe_exists_by_id(abstract) && +- ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) { +- DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", +- rpc_srv_get_pipe_cli_name(abstract), +- rpc_srv_get_pipe_srv_name(abstract))); +- } else { ++ if (!rpc_srv_pipe_exists_by_id(abstract)) { + return false; + } + ++ DEBUG(3, ("check_bind_req: %s -> %s rpc service\n", ++ rpc_srv_get_pipe_cli_name(abstract), ++ rpc_srv_get_pipe_srv_name(abstract))); ++ + context_fns = SMB_MALLOC_P(struct pipe_rpc_fns); + if (context_fns == NULL) { + DEBUG(0,("check_bind_req: malloc() failed!\n")); +-- +2.8.1 + + +From 511a212ad0bde4c84c6fb30625537cfc5052ac43 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 13:05:01 +0200 +Subject: [PATCH 31/40] CVE-2015-5370: s3:rpc_server: don't allow an existing + context to be changed in check_bind_req() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +An alter context can't change the syntax of an existing context, +a new context_id will be used for that. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit a995740d4e7fbd8fbb5c8c6280b73eaceae53574) +--- + source3/rpc_server/srv_pipe.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 0e6b073..4263a91 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -360,6 +360,28 @@ static bool check_bind_req(struct pipes_struct *p, + return false; + } + ++ for (context_fns = p->contexts; ++ context_fns != NULL; ++ context_fns = context_fns->next) ++ { ++ if (context_fns->context_id != context_id) { ++ continue; ++ } ++ ++ ok = ndr_syntax_id_equal(&context_fns->syntax, ++ abstract); ++ if (ok) { ++ return true; ++ } ++ ++ DEBUG(1,("check_bind_req: changing abstract syntax for " ++ "%s context_id=%u into %s not supported\n", ++ get_pipe_name_from_syntax(talloc_tos(), &context_fns->syntax), ++ (unsigned)context_id, ++ get_pipe_name_from_syntax(talloc_tos(), abstract))); ++ return false; ++ } ++ + /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ + if (!rpc_srv_pipe_exists_by_id(abstract)) { + return false; +-- +2.8.1 + + +From 6d8d1b5524548c7d2a5f4ba5d2f6263b3ed57590 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 8 Jul 2015 00:01:37 +0200 +Subject: [PATCH 32/40] CVE-2015-5370: s3:rpc_client: pass struct + pipe_auth_data to create_rpc_{bind_auth3,alter_context}() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit f556d9245c13d018d4e772f06d013ebe558703d9) +--- + source3/rpc_client/cli_pipe.c | 26 ++++++++++---------------- + 1 file changed, 10 insertions(+), 16 deletions(-) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 1c4ff01..3af3d8f 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -1816,9 +1816,8 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, + + static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *cli, +- uint32 rpc_call_id, +- enum dcerpc_AuthType auth_type, +- enum dcerpc_AuthLevel auth_level, ++ struct pipe_auth_data *auth, ++ uint32_t rpc_call_id, + DATA_BLOB *pauth_blob, + DATA_BLOB *rpc_out) + { +@@ -1828,8 +1827,8 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, + u.auth3._pad = 0; + + status = dcerpc_push_dcerpc_auth(mem_ctx, +- auth_type, +- auth_level, ++ auth->auth_type, ++ auth->auth_level, + 0, /* auth_pad_length */ + 1, /* auth_context_id */ + pauth_blob, +@@ -1861,9 +1860,8 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, + ********************************************************************/ + + static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, +- enum dcerpc_AuthType auth_type, +- enum dcerpc_AuthLevel auth_level, +- uint32 rpc_call_id, ++ struct pipe_auth_data *auth, ++ uint32_t rpc_call_id, + const struct ndr_syntax_id *abstract, + const struct ndr_syntax_id *transfer, + const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */ +@@ -1873,8 +1871,8 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, + NTSTATUS status; + + status = dcerpc_push_dcerpc_auth(mem_ctx, +- auth_type, +- auth_level, ++ auth->auth_type, ++ auth->auth_level, + 0, /* auth_pad_length */ + 1, /* auth_context_id */ + pauth_blob, +@@ -2300,9 +2298,7 @@ static NTSTATUS rpc_bind_next_send(struct tevent_req *req, + /* Now prepare the alter context pdu. */ + data_blob_free(&state->rpc_out); + +- status = create_rpc_alter_context(state, +- auth->auth_type, +- auth->auth_level, ++ status = create_rpc_alter_context(state, auth, + state->rpc_call_id, + &state->cli->abstract_syntax, + &state->cli->transfer_syntax, +@@ -2335,10 +2331,8 @@ static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, + /* Now prepare the auth3 context pdu. */ + data_blob_free(&state->rpc_out); + +- status = create_rpc_bind_auth3(state, state->cli, ++ status = create_rpc_bind_auth3(state, state->cli, auth, + state->rpc_call_id, +- auth->auth_type, +- auth->auth_level, + auth_token, + &state->rpc_out); + if (!NT_STATUS_IS_OK(status)) { +-- +2.8.1 + + +From 62166b207bd465b5c10e07dd23de4b9b2d44bfa4 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 8 Jul 2015 00:01:37 +0200 +Subject: [PATCH 33/40] CVE-2015-5370: s3:librpc/rpc: add auth_context_id to + struct pipe_auth_data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit cbf20b43d7b40e3b6ccf044f6f51a5adff1f5e6d) +--- + source3/librpc/rpc/dcerpc.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h +index 9452e85..c25b0f5 100644 +--- a/source3/librpc/rpc/dcerpc.h ++++ b/source3/librpc/rpc/dcerpc.h +@@ -42,6 +42,7 @@ struct pipe_auth_data { + bool verified_bitmask1; + + void *auth_ctx; ++ uint32_t auth_context_id; + + /* Only the client code uses these 3 for now */ + char *domain; +-- +2.8.1 + + +From dbfd333649e66f03c13e266e5e2007cd70acdc44 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 8 Jul 2015 00:01:37 +0200 +Subject: [PATCH 34/40] CVE-2015-5370: s3:rpc_client: make use of + pipe_auth_data->auth_context_id +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is better than using hardcoded values. +We need to use auth_context_id = 1 for authenticated +connections, as old Samba server (before this patchset) +will use a hardcoded value of 1. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit ae68d3f325c3880144b80385779c9445897646e6) +--- + source3/rpc_client/cli_pipe.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 3af3d8f..755d676 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -1314,7 +1314,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, + auth->auth_type, + auth->auth_level, + 0, /* auth_pad_length */ +- 1, /* auth_context_id */ ++ auth->auth_context_id, + &auth_token, + &auth_info); + if (!NT_STATUS_IS_OK(ret)) { +@@ -1830,7 +1830,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, + auth->auth_type, + auth->auth_level, + 0, /* auth_pad_length */ +- 1, /* auth_context_id */ ++ auth->auth_context_id, + pauth_blob, + &u.auth3.auth_info); + if (!NT_STATUS_IS_OK(status)) { +@@ -1874,7 +1874,7 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, + auth->auth_type, + auth->auth_level, + 0, /* auth_pad_length */ +- 1, /* auth_context_id */ ++ auth->auth_context_id, + pauth_blob, + &auth_info); + if (!NT_STATUS_IS_OK(status)) { +@@ -2704,6 +2704,7 @@ NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx, + + result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM; + result->auth_level = DCERPC_AUTH_LEVEL_CONNECT; ++ result->auth_context_id = 1; + + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, ""); +@@ -2728,6 +2729,7 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, + + result->auth_type = DCERPC_AUTH_TYPE_NONE; + result->auth_level = DCERPC_AUTH_LEVEL_NONE; ++ result->auth_context_id = 0; + + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, ""); +@@ -2765,6 +2767,7 @@ static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, + + result->auth_type = auth_type; + result->auth_level = auth_level; ++ result->auth_context_id = 1; + + result->user_name = talloc_strdup(result, username); + result->domain = talloc_strdup(result, domain); +@@ -2836,6 +2839,7 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, + + result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL; + result->auth_level = auth_level; ++ result->auth_context_id = 1; + + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, domain); +@@ -3500,6 +3504,7 @@ NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli, + } + auth->auth_type = DCERPC_AUTH_TYPE_KRB5; + auth->auth_level = auth_level; ++ auth->auth_context_id = 1; + + if (!username) { + username = ""; +@@ -3570,6 +3575,7 @@ NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli, + } + auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO; + auth->auth_level = auth_level; ++ auth->auth_context_id = 1; + + if (!username) { + username = ""; +@@ -3644,6 +3650,7 @@ NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, + } + auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO; + auth->auth_level = auth_level; ++ auth->auth_context_id = 1; + + if (!username) { + username = ""; +-- +2.8.1 + + +From 2d58dfb478eccb3f93e1d56f1d2bbff1577d3c02 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 8 Jul 2015 00:01:37 +0200 +Subject: [PATCH 35/40] CVE-2015-5370: s3:rpc_server: make use of + pipe_auth_data->auth_context_id +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is better than using hardcoded values. +We need to use the value the client used in the BIND request. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 2bc617293a5d8652e484af69660b3646f3d48690) +--- + source3/rpc_server/rpc_ncacn_np.c | 1 + + source3/rpc_server/srv_pipe.c | 11 +++++++---- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c +index f2e9d10..c0f24a6 100644 +--- a/source3/rpc_server/rpc_ncacn_np.c ++++ b/source3/rpc_server/rpc_ncacn_np.c +@@ -781,6 +781,7 @@ static NTSTATUS rpc_pipe_open_external(TALLOC_CTX *mem_ctx, + } + result->auth->auth_type = DCERPC_AUTH_TYPE_NONE; + result->auth->auth_level = DCERPC_AUTH_LEVEL_NONE; ++ result->auth->auth_context_id = 0; + + status = rpccli_anon_bind_data(result, &auth); + if (!NT_STATUS_IS_OK(status)) { +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index 4263a91..d6c4118 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -534,6 +534,7 @@ static bool pipe_spnego_auth_bind(struct pipes_struct *p, + + p->auth.auth_ctx = spnego_ctx; + p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO; ++ p->auth.auth_context_id = auth_info->auth_context_id; + + DEBUG(10, ("SPNEGO auth started\n")); + +@@ -644,6 +645,7 @@ static bool pipe_schannel_auth_bind(struct pipes_struct *p, + /* We're finished with this bind - no more packets. */ + p->auth.auth_ctx = schannel_auth; + p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL; ++ p->auth.auth_context_id = auth_info->auth_context_id; + + p->pipe_bound = True; + +@@ -688,6 +690,7 @@ static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p, + + p->auth.auth_ctx = ntlmssp_state; + p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP; ++ p->auth.auth_context_id = auth_info->auth_context_id; + + DEBUG(10, (__location__ ": NTLMSSP auth started\n")); + +@@ -1173,6 +1176,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + p->pipe_bound = True; + /* The session key was initialized from the SMB + * session in make_internal_rpc_pipe_p */ ++ p->auth.auth_context_id = 0; + } + + ZERO_STRUCT(u.bind_ack); +@@ -1218,12 +1222,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p, + } + + if (auth_resp.length) { +- + status = dcerpc_push_dcerpc_auth(pkt, + auth_type, + auth_info.auth_level, +- 0, +- 1, /* auth_context_id */ ++ 0, /* pad_len */ ++ p->auth.auth_context_id, + &auth_resp, + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { +@@ -1646,7 +1649,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + auth_info.auth_type, + auth_info.auth_level, + pad_len, +- 1, /* auth_context_id */ ++ p->auth.auth_context_id, + &auth_resp, + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { +-- +2.8.1 + + +From 43a77c90f877df714e71274143ab01eef27271cb Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 8 Jul 2015 00:01:37 +0200 +Subject: [PATCH 36/40] CVE-2015-5370: s3:librpc/rpc: make use of + auth->auth_context_id in dcerpc_add_auth_footer() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 61faaa63e7e610308c72ae4c41a5c7b5b7312685) +--- + source3/librpc/rpc/dcerpc_helpers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c +index e4d0e3a..977a372 100644 +--- a/source3/librpc/rpc/dcerpc_helpers.c ++++ b/source3/librpc/rpc/dcerpc_helpers.c +@@ -741,7 +741,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, + auth->auth_type, + auth->auth_level, + pad_len, +- 1 /* context id. */, ++ auth->auth_context_id, + &auth_blob, + &auth_info); + if (!NT_STATUS_IS_OK(status)) { +-- +2.8.1 + + +From fd2a01c93e86f1f7d23700c25cde5c84743bc289 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 8 Jul 2015 00:01:37 +0200 +Subject: [PATCH 37/40] CVE-2015-5370: s3:librpc/rpc: verify auth_context_id in + dcerpc_check_auth() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 0cf3151c843e2c779b534743b455e630d89e2ba9) +--- + source3/librpc/rpc/dcerpc_helpers.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c +index 977a372..b00cf1bf 100644 +--- a/source3/librpc/rpc/dcerpc_helpers.c ++++ b/source3/librpc/rpc/dcerpc_helpers.c +@@ -881,6 +881,10 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, + return NT_STATUS_INVALID_PARAMETER; + } + ++ if (auth_info.auth_context_id != auth->auth_context_id) { ++ return NT_STATUS_INVALID_PARAMETER; ++ } ++ + pkt_trailer->length -= auth_length; + data = data_blob_const(raw_pkt->data + header_size, + pkt_trailer->length); +-- +2.8.1 + + +From b2f0b95a0cdeeaad2ca9b993940fbbb5687a3509 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 7 Jul 2015 22:51:18 +0200 +Subject: [PATCH 38/40] CVE-2015-5370: s3:rpc_client: verify auth_context_id in + rpc_pipe_bind_step_one_done() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 93a0f92b8ebecb38f92d3b2c9a946b486ee91d3c) +--- + source3/rpc_client/cli_pipe.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c +index 755d676..ee33e80 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -2052,6 +2052,14 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) + return; + } + ++ if (auth.auth_context_id != pauth->auth_context_id) { ++ DEBUG(0, (__location__ " Auth context id %u mismatch expected %u.\n", ++ (unsigned)auth.auth_context_id, ++ (unsigned)pauth->auth_context_id)); ++ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); ++ return; ++ } ++ + break; + } + +-- +2.8.1 + + +From 6e814c0173c4e74469d6f884f6eef3fc117e7117 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Wed, 8 Jul 2015 00:01:37 +0200 +Subject: [PATCH 39/40] CVE-2015-5370: s3:rpc_server: verify auth_context_id in + api_pipe_{bind_auth3,alter_context} +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 3ef461d8304ee36184cd7a3963676eedff4ef1eb) +--- + source3/rpc_server/srv_pipe.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c +index d6c4118..26c4ee0 100644 +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -1364,6 +1364,14 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) + goto err; + } + ++ if (auth_info.auth_context_id != p->auth.auth_context_id) { ++ DEBUG(0, ("Auth context id mismatch! Client sent %u, " ++ "but auth was started as level %u!\n", ++ (unsigned)auth_info.auth_context_id, ++ (unsigned)p->auth.auth_context_id)); ++ goto err; ++ } ++ + switch (auth_info.auth_type) { + case DCERPC_AUTH_TYPE_NTLMSSP: + ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx, +@@ -1545,6 +1553,14 @@ static bool api_pipe_alter_context(struct pipes_struct *p, + goto err_exit; + } + ++ if (auth_info.auth_context_id != p->auth.auth_context_id) { ++ DEBUG(0, ("Auth context id mismatch! Client sent %u, " ++ "but auth was started as level %u!\n", ++ (unsigned)auth_info.auth_context_id, ++ (unsigned)p->auth.auth_context_id)); ++ goto err_exit; ++ } ++ + switch (auth_info.auth_type) { + case DCERPC_AUTH_TYPE_SPNEGO: + spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx, +-- +2.8.1 + + +From dca4488d6ce0477cac4bf4ab878444d64a83ebfb Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <me...@samba.org> +Date: Tue, 22 Dec 2015 21:23:14 +0100 +Subject: [PATCH 40/40] CVE-2015-5370: s3:rpc_client: disconnect connection on + protocol errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 + +Signed-off-by: Stefan Metzmacher <me...@samba.org> +Reviewed-by: Günther Deschner <g...@samba.org> +(cherry picked from commit 024d3b263a2879cee4fb7794d70f253c948cc043) +--- + 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 ee33e80..a3810f0 100644 +--- a/source3/rpc_client/cli_pipe.c ++++ b/source3/rpc_client/cli_pipe.c +@@ -953,6 +953,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; + } +@@ -962,6 +968,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; + } +@@ -979,6 +991,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; +@@ -1003,12 +1037,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; + } + +@@ -1016,6 +1062,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) @@ Diff output truncated at 100000 characters. @@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.