Re: ZDI-CAN-33549: New Vulnerability Report

From: Namjae Jeon

Date: Fri Oct 23 2026 - 06:41:52 EST


On Fri, Oct 23, 2026 at 6:04 PM Stefan Metzmacher <metze@xxxxxxxxx> wrote:
>
> Am 22.10.26 um 00:16 schrieb Stefan Metzmacher via samba-technical:
> > Hi HYEONTAE LEE,
> >
> > would you be able to test if this is reproducable on this branch:
> > https://git.samba.org/?p=metze/linux/wip.git;a=shortlog;h=refs/heads/for-7.5/smbdirect
> > git clone -b for-7.5/smbdirect https://git.samba.org/metze/linux/wip.git for-7.5-smbdirect
> >
> > I guess it's already fixed with that.
> >
> > Thanks!
> > metze
> >
> > Am 21.10.26 um 23:16 schrieb zdi-disclosures@xxxxxxxxxxxxxx:
> >> ZDI-CAN-33549: Linux Kernel KSMBD SMB Direct Integer Underflow Remote Code Execution Vulnerability
> >>
> >> -- CVSS -----------------------------------------
> >>
> >> 9.0: AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
> >>
> >> -- ABSTRACT -------------------------------------
> >>
> >> Trend Micro's Zero Day Initiative has identified a vulnerability affecting the following products:
> >> Linux - Kernel KSMBD
> >>
> >> -- VULNERABILITY DETAILS ------------------------
> >> * Version Tested:7.3-rc3
> >> * Platform Tested:debian trixie
> >>
> >> ---
> >>
> >> ### Analysis
> >>
> >> integer underflow in smbdirect_connection_rdma_xmit()
> >> The reproduce kernel built with CONFIG_SMB_SERVER_SMBDIRECT=y + CONFIG_RDMA_RXE=y
> >> Here is the target requirement
> >> 1) RDMA device
> >> 2) writable share
> >> 3) smb direct (ubuntu only)
> >>
> >> ~~~C++
> >> int smbdirect_connection_rdma_xmit(struct smbdirect_socket *sc,
> >> void *buf, size_t buf_len,
> >> struct smbdirect_buffer_descriptor_v1 *desc,
> >> size_t desc_len,
> >> bool is_read)
> >> {
> >> ...
> >> for (i = 0; i < desc_len / sizeof(*desc); i++) {
> >> if (!buf_len)
> >> break;
> >>
> >> desc_buf_len = le32_to_cpu(desc[i].length);
> >> if (!desc_buf_len)
> >> return -EINVAL;
> >>
> >> if (desc_buf_len > buf_len) {
> >> desc_buf_len = buf_len;
> >> desc[i].length = cpu_to_le32(desc_buf_len);
> >> buf_len = 0; // (1)
> >> }
> >>
> >> credits_needed += smbdirect_connection_calc_rw_credits(sc,
> >> desc_buf,
> >> desc_buf_len);
> >> desc_buf += desc_buf_len;
> >> buf_len -= desc_buf_len; // (2) integer underflow, and leads to heap overflow within rxe_mr_copy()
> >> desc_num++;
> >> }
>
> As far as I can see the problem is solved in by patches,
> but we should have a simple fix first.
>
> I think removing ' buf_len = 0;' should be enough for a quick fix,
> then 'buf_len -= desc_buf_len;' will result in buf_len == 0 and the next
> iteration will break with if (!buf_len).
>
> Namjae, do you agree? Can you create such a quick fix?
Agreed, Please check the attached patch.
Thanks for checking this issue!
From 5b8ce2e5670ebe31970b6718403197ae51d47e43 Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@xxxxxxxxxx>
Date: Fri, 23 Oct 2026 19:26:09 +0900
Subject: [PATCH] smb: smbdirect: fix buffer length underflow in RDMA transfers
From: Stefan Metzmacher <metze@xxxxxxxxx>

When a remote buffer descriptor is larger than the remaining local
buffer, smbdirect_connection_rdma_xmit() clamps its length and sets
buf_len to zero. The common accounting code then subtracts the clamped
length from buf_len, causing it to underflow. If another descriptor
follows, the loop processes it with a wrapped remaining length and
includes memory beyond the local buffer in the RDMA transfer.

A client can trigger an out-of-bounds kernel write with an SMB WRITE
request, or an out-of-bounds kernel read with an SMB READ request, by
supplying multiple RDMA buffer descriptors with an oversized descriptor
before the last one.

Remove the premature assignment to buf_len. Subtracting the clamped length
already consumes the remaining buffer, so the next iteration stops and
only descriptors within the local buffer are used to build work requests.

Fixes: e628bf939aaf ("ksmbd: reduce descriptor size if remaining bytes is less than request size")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Stefan Metzmacher <metze@xxxxxxxxx>
Signed-off-by: Namjae Jeon <linkinjeon@xxxxxxxxxx>
---
fs/smb/smbdirect/rw.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/fs/smb/smbdirect/rw.c b/fs/smb/smbdirect/rw.c
index 6fe38042cfb9..cb142c3c50b2 100644
--- a/fs/smb/smbdirect/rw.c
+++ b/fs/smb/smbdirect/rw.c
@@ -143,7 +143,6 @@ int smbdirect_connection_rdma_xmit(struct smbdirect_socket *sc,
if (desc_buf_len > buf_len) {
desc_buf_len = buf_len;
desc[i].length = cpu_to_le32(desc_buf_len);
- buf_len = 0;
}

credits_needed += smbdirect_connection_calc_rw_credits(sc,
--
2.25.1