summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2020-11-13 11:27:19 +0100
committerJule Anger <janger@samba.org>2021-11-09 19:45:34 +0000
commit2f0bc04afe27af91901c66b2f4220129cabaf8a7 (patch)
tree1f5ce2c66d23ff83ae3834eddb4a496e174d86af
parentc00e5fc2c646ef56a457d3850fb4a6e4d8d45294 (diff)
downloadsamba-2f0bc04afe27af91901c66b2f4220129cabaf8a7.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>
-rw-r--r--librpc/rpc/dcesrv_core.c47
1 files changed, 16 insertions, 31 deletions
diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
index 289f734ea00..07e14567c84 100644
--- a/librpc/rpc/dcesrv_core.c
+++ b/librpc/rpc/dcesrv_core.c
@@ -750,6 +750,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)
{
@@ -2110,10 +2113,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) {
@@ -2123,10 +2123,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);
}
}
@@ -2144,10 +2141,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) {
@@ -2168,10 +2162,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;
@@ -2224,12 +2215,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);
}
}
@@ -2246,20 +2235,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 */
@@ -2298,9 +2284,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;