1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
From 70754b01fb272604e90f8b886ec4ff73ca6ab38f Mon Sep 17 00:00:00 2001
From: ZjW1nd <zj_w1nd@qq.com>
Date: Mon, 18 Aug 2025 10:47:55 +0800
Subject: [PATCH 2/4] [Security]: fix NULL deref on alloc failure in
dcerpc_bind_async
Origin: upstream, https://github.com/sahlberg/libsmb2/commit/70754b01fb272604e90f8b886ec4ff73ca6ab38f
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1116446
Root cause: unchecked smb2_alloc_data results for p_cont_elem and transfer_syntaxes could be NULL.
Trigger: low-memory or crafted conditions causing allocator to return NULL; code then writes to transfer_syntaxes[0].
Impact: client crash (DoS) due to NULL pointer dereference.
Fix: guard all allocations in dcerpc_bind_async; on failure set error, free PDU, and return -ENOMEM; avoid invoking callbacks before initialization.
Backported by: Matheus Polkorny <mpolkorny@gmail.com>
Changes:
- Update hunks' offsets.
---
lib/dcerpc.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/lib/dcerpc.c b/lib/dcerpc.c
index d0be632..a0c6174 100644
--- a/lib/dcerpc.c
+++ b/lib/dcerpc.c
@@ -1756,6 +1756,11 @@ dcerpc_bind_async(struct dcerpc_context *dce, dcerpc_cb cb,
pdu->bind.n_context_elem = dce->smb2->ndr ? 1 : 2;
pdu->bind.p_cont_elem = smb2_alloc_data(dce->smb2, pdu->payload,
pdu->bind.n_context_elem * sizeof(struct p_cont_elem_t));
+ if (pdu->bind.p_cont_elem == NULL) {
+ smb2_set_error(dce->smb2, "Failed to allocate p_cont_elem");
+ dcerpc_free_pdu(dce, pdu);
+ return -ENOMEM;
+ }
pce = pdu->bind.p_cont_elem;
if (dce->smb2->ndr == 0 || dce->smb2->ndr == 1) {
pce->p_cont_id = 0;
@@ -1764,6 +1769,11 @@ dcerpc_bind_async(struct dcerpc_context *dce, dcerpc_cb cb,
pce->transfer_syntaxes = smb2_alloc_data(
dce->smb2, pdu->payload,
pce->n_transfer_syn * sizeof(struct p_cont_elem_t *));
+ if (pce->transfer_syntaxes == NULL) {
+ smb2_set_error(dce->smb2, "Failed to allocate transfer_syntaxes");
+ dcerpc_free_pdu(dce, pdu);
+ return -ENOMEM;
+ }
pce->transfer_syntaxes[0] = &ndr32_syntax;
pce++;
}
@@ -1774,6 +1784,11 @@ dcerpc_bind_async(struct dcerpc_context *dce, dcerpc_cb cb,
pce->transfer_syntaxes = smb2_alloc_data(
dce->smb2, pdu->payload,
pce->n_transfer_syn * sizeof(struct p_cont_elem_t *));
+ if (pce->transfer_syntaxes == NULL) {
+ smb2_set_error(dce->smb2, "Failed to allocate transfer_syntaxes");
+ dcerpc_free_pdu(dce, pdu);
+ return -ENOMEM;
+ }
pce->transfer_syntaxes[0] = &ndr64_syntax;
}
--
2.51.0
|