diff options
author | Stefan Metzmacher <metze@samba.org> | 2020-11-13 11:27:19 +0100 |
---|---|---|
committer | Jule Anger <janger@samba.org> | 2021-11-08 10:46:45 +0100 |
commit | 793cdac7d383052d8edb794fab6bc0f7201519ad (patch) | |
tree | 9af7af6d368ace92d527fd87b73b1d6ed16fe654 /librpc | |
parent | a106cfd09204fa637096965b58ad39c268375b99 (diff) | |
download | samba-793cdac7d383052d8edb794fab6bc0f7201519ad.tar.gz |
CVE-2021-23192: dcesrv_core: add dcesrv_fault_disconnect0() that skips DCERPC_PFC_FLAG_DID_NOT_EXECUTE
That makes the callers much simpler and allow better debugging.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14875
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Samuel Cabrero <scabrero@samba.org>
Diffstat (limited to 'librpc')
-rw-r--r-- | librpc/rpc/dcesrv_core.c | 47 |
1 files changed, 16 insertions, 31 deletions
diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c index 0c2d83b4b17..ffaa9019d4b 100644 --- a/librpc/rpc/dcesrv_core.c +++ b/librpc/rpc/dcesrv_core.c @@ -736,6 +736,9 @@ static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call, _dcesrv_fault_disconnect_flags(call, fault_code, \ DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \ __func__, __location__) +#define dcesrv_fault_disconnect0(call, fault_code) \ + _dcesrv_fault_disconnect_flags(call, fault_code, 0, \ + __func__, __location__) static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c) { @@ -2097,10 +2100,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, * Note that we don't check against the negotiated * max_recv_frag, but a hard coded value. */ - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - frag_length too large"); - return dcesrv_fault(call, - DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) { @@ -2110,10 +2110,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, * if DCERPC_PFC_FLAG_CONC_MPX was negotiated. */ if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) { - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - " - "existing pending call without CONN_MPX"); - return dcesrv_fault(call, + return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR); } } @@ -2131,10 +2128,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, TALLOC_FREE(call); call = dce_conn->incoming_fragmented_call_list; } - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - " - "existing fragmented call"); - return dcesrv_fault(call, + return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) { @@ -2155,10 +2149,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, existing = dcesrv_find_fragmented_call(dce_conn, call->pkt.call_id); if (existing == NULL) { - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - " - "no existing fragmented call"); - return dcesrv_fault(call, + return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR); } er = &existing->pkt.u.request; @@ -2211,12 +2202,10 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, * here, because we don't want to set * DCERPC_PFC_FLAG_DID_NOT_EXECUTE */ - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - failed"); if (call->fault_code == 0) { call->fault_code = DCERPC_FAULT_ACCESS_DENIED; } - return dcesrv_fault(call, call->fault_code); + return dcesrv_fault_disconnect0(call, call->fault_code); } } @@ -2233,20 +2222,17 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, */ available = dce_conn->max_total_request_size; if (er->stub_and_verifier.length > available) { - dcesrv_call_disconnect_after(existing, - "dcesrv_auth_request - existing payload too large"); - return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault_disconnect0(existing, + DCERPC_FAULT_ACCESS_DENIED); } available -= er->stub_and_verifier.length; if (nr->alloc_hint > available) { - dcesrv_call_disconnect_after(existing, - "dcesrv_auth_request - alloc hint too large"); - return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault_disconnect0(existing, + DCERPC_FAULT_ACCESS_DENIED); } if (nr->stub_and_verifier.length > available) { - dcesrv_call_disconnect_after(existing, - "dcesrv_auth_request - new payload too large"); - return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault_disconnect0(existing, + DCERPC_FAULT_ACCESS_DENIED); } alloc_hint = er->stub_and_verifier.length + nr->alloc_hint; /* allocate at least 1 byte */ @@ -2285,9 +2271,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, * Up to 4 MByte are allowed by all fragments */ if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) { - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - initial alloc hint too large"); - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault_disconnect0(call, + DCERPC_FAULT_ACCESS_DENIED); } dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST); return NT_STATUS_OK; |