From 1dbcb533af16de2ae26e6d602da63a2ec10c0f84 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Nov 2020 17:05:21 +0100 Subject: [PATCH] dcerpc_util: let dcerpc_pull_auth_trailer() check that auth_offset is 4 bytes aligned That what Windows also asserts. It also makes sure that ndr_pull_dcerpc_auth() will start with ndr->offset = 0 and don't tries to eat possible padding. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 890fff1ca0c4e1eb8ef26c4f88aa18aeda3afc4f) --- librpc/rpc/dcerpc_util.c | 18 +++++++++++------- selftest/knownfail.d/dcerpc-auth-pad | 1 - 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 948e8840d4d..8684df35b7f 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -239,8 +239,10 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, enum ndr_err_code ndr_err; uint16_t data_and_pad; uint16_t auth_length; + uint16_t auth_offset; uint32_t tmp_length; uint32_t max_pad_len = 0; + DATA_BLOB auth_blob; ZERO_STRUCTP(auth); if (_auth_length != NULL) { @@ -280,8 +282,16 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, } data_and_pad = pkt_trailer->length - auth_length; + auth_offset = pkt->frag_length - auth_length; + if ((auth_offset % 4) != 0) { + DBG_WARNING("auth_offset[%u] not 4 byte aligned\n", + (unsigned)auth_offset); + return NT_STATUS_RPC_PROTOCOL_ERROR; + } - ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx); + auth_blob = data_blob_const(pkt_trailer->data + data_and_pad, + auth_length); + ndr = ndr_pull_init_blob(&auth_blob, mem_ctx); if (!ndr) { return NT_STATUS_NO_MEMORY; } @@ -290,12 +300,6 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } - ndr_err = ndr_pull_advance(ndr, data_and_pad); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(ndr); - return ndr_map_error2ntstatus(ndr_err); - } - ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); diff --git a/selftest/knownfail.d/dcerpc-auth-pad b/selftest/knownfail.d/dcerpc-auth-pad index dd407ab5459..9ea88114ce7 100644 --- a/selftest/knownfail.d/dcerpc-auth-pad +++ b/selftest/knownfail.d/dcerpc-auth-pad @@ -17,7 +17,6 @@ ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_tail_pad_ntlm_auth3 ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_tail_pad_spnego_alter ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_auth_tail_pad_spnego_auth3 -^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_spnego_integrity_bind_auth_align2 ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_schannel_invalid_alter_no_padding.*chgdcpass ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_schannel_invalid_alter_tail_padding.*chgdcpass ^samba.tests.dcerpc.raw_protocol.samba.tests.dcerpc.raw_protocol.TestDCERPC_BIND.test_schannel_invalid_bind_no_padding.*chgdcpass