public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [BUG] Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free
@ 2026-04-02 11:06 ven0mfuzzer
  2026-04-02 15:05 ` Paulo Alcantara
  2026-04-03 22:08 ` Steve French
  0 siblings, 2 replies; 3+ messages in thread
From: ven0mfuzzer @ 2026-04-02 11:06 UTC (permalink / raw)
  To: Ronnie Sahlberg, Tom Talpey, Paulo Alcantara, Steve French,
	Bharath SM, Shyam Prasad N
  Cc: linux-cifs, linux-kernel, samba-technical

Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free

  1. Vulnerability Title

Linux Kernel CIFS Client SMB2 Compound Request KFENCE-Confirmed Double-Free Vulnerability (ksmbd)

  2. High-Level Overview

This report describes the same double-free vulnerability in the Linux kernel CIFS client as crash_001 (KASAN detection), now independently confirmed by KFENCE (Kernel Electric-Fence). When the CIFS client sends a compound `CREATE + CLOSE` request (e.g., via `smb2_unlink()`), a malicious server or MITM can return `STATUS_IO_TIMEOUT` in the CREATE response, causing a retry loop. On the error-path of the retry, `SMB2_open_free()` is called a second time on an already-freed `cifs_small_rq` mempool object (448 bytes), producing a double-free.

The KFENCE detection provides additional forensic detail over the KASAN report in crash_001: precise timestamps, exact object lifetime (27.5 seconds), exact slab cache name (`cifs_small_rq`), and confirmation that both frees are issued by the same task — ruling out any race condition. This is a deterministic, single-threaded double-free.

This vulnerability was discovered using ven0mfuzzer, our custom-designed MITM-based network filesystem fuzzer developed by our team. Following the common syzkaller practice, we submit the kernel crash trace as the primary reproduction artifact.

  3. Affected Product and Version Information

Product: Linux Kernel (upstream mainline)
Affected Component: `fs/smb/client/smb2inode.c` — `smb2_unlink()` (line 1186)
Supporting Components:
- `fs/smb/client/smb2pdu.c` — `SMB2_open_free()` does not null freed pointer (line 3244)

  Tested Versions (confirmed vulnerable)
- Linux kernel 6.19.0 (mainline, commit `44331bd6a610`, gcc 11.4.0, built 2026-02-13)
- Linux kernel 6.12.74 (LTS, used in Google kernelCTF COS target)

  Affected Version Range
All kernels from approximately 6.0 through 6.19 (current mainline at time of report) with SMB2 compound replay support are believed affected.

  Affected Distributions and Products

 |  Vendor / Product  |  Notes  | 
 | --- | --- | 
 |  Red Hat Enterprise Linux (RHEL 9.x)  |  Ships kernels >= 5.14 with backported SMB2 compound replay  | 
 |  Ubuntu (22.04 LTS, 24.04 LTS)  |  HWE kernels 6.x include vulnerable code  | 
 |  SUSE Linux Enterprise Server (SLES 15 SP5+)  |  Kernel 6.x based  | 
 |  Debian (Bookworm, Trixie)  |  Kernels 6.1+  | 
 |  Fedora (39+)  |  Kernels 6.5+  | 
 |  Amazon Linux 2023  |  Kernel 6.1 LTS based  | 
 |  Google ChromeOS / COS  |  kernelCTF target, confirmed vulnerable on 6.12.74  | 

  4. Root Cause Analysis

  4.a. Detailed Description

This is the same root cause as crash_001: `smb2_unlink()` calls `SMB2_open_free()` twice on the same stack-local `open_iov` array pointer. The first free occurs during normal cleanup after `compound_send_recv()` returns `-EAGAIN` (due to `STATUS_IO_TIMEOUT`). The retry loop (`goto again`) reuses the same `open_iov` array without clearing it. If `SMB2_open_init()` fails on the second iteration (due to reconnect state), the `err_free` label calls `SMB2_open_free()` again on the stale pointer.

The KFENCE report captures all three critical events:

1. Allocation at `smb2_unlink+0x470` — `SMB2_open_init` allocates the CREATE request buffer
2. First free at `smb2_unlink+0x5db` — normal cleanup after `compound_send_recv` (line 1263)
3. Invalid second free at `smb2_unlink+0x81c` — `err_free` label (line 1289)

  4.b. Code Flow

---
smb2_unlink()                    [fs/smb/client/smb2inode.c:1186]
  again:
    SMB2_open_init()             ← allocates cifs_small_rq object (448B)
    compound_send_recv()         ← server returns STATUS_IO_TIMEOUT → -EAGAIN
    SMB2_open_free(&rqst[0])    ← FIRST FREE (line 1263), does NOT null open_iov[0]
    goto again
  again:
    memset(rqst, 0, ...)         ← clears rqst[] but NOT open_iov[] (stale pointer!)
    SMB2_open_init()             ← fails (connection being reconnected) → rc != 0
    goto err_free
  err_free:
    SMB2_open_free(&rqst[0])    ← SECOND FREE of already-freed buffer!
---

  4.c. KFENCE Crash Trace

This vulnerability was discovered by ven0mfuzzer. The following kernel trace is submitted following syzkaller's common practice of providing the raw crash trace as the primary reproduction evidence:

---
: VFS: Signing Key   d8 d6 c0 c2 b7 56 41 83 e9 d7 b5 fd 2c df 47 62
[ 1087.254230] CIFS: VFS: ServerIn Key  5b 78 90 2a f0 90 67 84 da 43 e8 f1 a8 43 eb 91
[ 1087.254673] CIFS: VFS: ServerOut Key 93 3a 5d ae db 4a 4b fb 24 4b c5 b8 f9 e3 47 29
[ 1087.258673] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
[ 1087.259195] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
[ 1087.259715] ==================================================================
[ 1087.260125] BUG: KFENCE: invalid free in mempool_free+0xde/0x130
[ 1087.260125] 
[ 1087.260556] Invalid free of 0xffff8881f5cc4e40 (in kfence-#97):
[ 1087.260893]  mempool_free+0xde/0x130
[ 1087.261124]  cifs_small_buf_release+0x41/0x70
[ 1087.261392]  SMB2_open_free+0x78/0x1b0
[ 1087.261631]  smb2_unlink+0x81c/0x8d0
[ 1087.261870]  __cifs_unlink+0x830/0x1890
[ 1087.262134]  vfs_unlink+0x2f0/0xbd0
[ 1087.262369]  filename_unlinkat+0x345/0x6d0
[ 1087.262628]  __x64_sys_unlinkat+0xc4/0x130
[ 1087.262886]  do_syscall_64+0x111/0x690
[ 1087.263125]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 1087.263427] 
[ 1087.263531] kfence-#97: 0xffff8881f5cc4e40-0xffff8881f5cc4fff, size=448, cache=cifs_small_rq
[ 1087.263531] 
[ 1087.264219] allocated by task 1881 on cpu 0 at 1059.756104s (27.508113s ago):
[ 1087.264648]  mempool_alloc_noprof+0x18a/0x2c0
[ 1087.264919]  cifs_small_buf_get+0x36/0x80
[ 1087.265210]  __smb2_plain_req_init+0x4b/0x1140
[ 1087.265487]  SMB2_open_init+0x1ae/0x37f0
[ 1087.265735]  smb2_unlink+0x470/0x8d0
[ 1087.265974]  __cifs_unlink+0x830/0x1890
[ 1087.266226]  vfs_unlink+0x2f0/0xbd0
[ 1087.266460]  filename_unlinkat+0x345/0x6d0
[ 1087.266717]  __x64_sys_unlinkat+0xc4/0x130
[ 1087.266975]  do_syscall_64+0x111/0x690
[ 1087.267214]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 1087.267514] 
[ 1087.267618] freed by task 1881 on cpu 0 at 1087.241106s (0.026511s ago):
[ 1087.268109]  mempool_free+0xde/0x130
[ 1087.268352]  cifs_small_buf_release+0x41/0x70
[ 1087.268620]  SMB2_open_free+0x78/0x1b0
[ 1087.268858]  smb2_unlink+0x5db/0x8d0
[ 1087.269091]  __cifs_unlink+0x830/0x1890
[ 1087.269293]  vfs_unlink+0x2f0/0xbd0
[ 1087.269481]  filename_unlinkat+0x345/0x6d0
[ 1087.269687]  __x64_sys_unlinkat+0xc4/0x130
[ 1087.269895]  do_syscall_64+0x111/0x690
[ 1087.270086]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 1087.270327] 
[ 1087.270417] CPU: 0 UID: 0 PID: 1881 Comm: rm Tainted: G    B               6.19.0-g44331bd6a610-dirty #5 PREEMPT(lazy) 
[ 1087.270900] Tainted: [B]=BAD_PAGE
[ 1087.271061] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[ 1087.271561] ==================================================================
[ 1087.723901] CIFS: VFS: \\10.0.0.2 RFC 1002 unknown response type 0x8
[ 1087.739764] CIFS: VFS: \\10.0.0.2\IPC$ validate protocol negotiate failed: -11
[ 1087.740391] CIFS: VFS: \\10.0.0.2\IPC$ reconnect tcon failed rc = -5
[ 1087.746271] CIFS: VFS: generate_smb3signingkey: dumping generated AES session keys
[ 1087.746842] CIFS: VFS: Session Id    02 00 00 00 00 00 00 00
[ 1087.747238] CIFS: VFS: Cipher type   1
[ 1087.747464] CIFS: VFS: Session Key   71 85 72 ad 7c b4 da e7 cf dc c0 ae 3a 07 98 19
[ 1087.747888] CIFS: VFS: Signing Key   88 3f d1 03 8b 13 17 97 88 be 52 23 9b 8d a9 ed
[ 1087.748463] CIFS: VFS: ServerIn Key  0e 28 bd af 95 9d 5d e4 34 0a d5 de a6 9a 74 0d
[ 1087.749077] CIFS: VFS: ServerOut Key ba a1 76 7c c0 b9 32 db 27 09 85 1a e7 7d cf 65
[ 1087.754602] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -13
[ 1087.755289] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
[ 1087.758970] CIFS: VFS: smb2_get_data_area_len: invalid data area (off=10608 len=24)
[ 1087.759770] CIFS: VFS: \\10.0.0.2\fuzzshare Malformed ioctl resp: len 24 offset 10608
[ 1087.760271] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -5
[ 1087.760742] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
[ 1087.764494] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
[ 1087.765178] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
[ 1088.197368] CIFS: VFS: Bad protocol string signature header 420053fe
[ 1088.198145] CIFS: VFS: Bad SMB detected. The Mid=16
[ 1088.198652] 00000000: 420053fe 00010040 00000000 000a0005  .S.B@...........
[ 1088.199364] 00000010: 00000001 00000000 00000010 00000000  ................
[ 1088.200070] 00000020: 00000776 00000004 00000002 00000002  v...............
[ 1088.459625] CIFS: VFS: \\10.0.0.2 RFC 1002 unknown response type 0x42
[ 1089.503269] CIFS: VFS: generate_smb3signingkey: dumping generated AES session keys
[ 1089.503705] CIFS: VFS: Session Id    02 00 00 00 00 00 00 00
[ 1089.504013] CIFS: VFS: Cipher type   1
[ 1089.504229] CIFS: VFS: Session Key   d6 56 c8 0b 7a 8f 2c 81 4a 9a 16 b8 ef a6 df 50
[ 1089.504575] CIFS: VFS: Signing Key   b6 36 17 ad 2f 1d d5 d6 21 0a 98 37 50 9a 31 08
[ 1089.504914] CIFS: VFS: ServerIn Key  b6 c4 17 a9 16 ed 60 72 14 1b 64 6b d5 20 5f f2
[ 1089.505485] CIFS: VFS: ServerOut Key e1 8c 7f af 9e 04 ed 2c 67 47 63 68 e4 eb 9e 2b
[ 1089.718373] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
[ 1089.719252] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
[ 1090.142104] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -5
[ 1090.142986] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
[ 1090.353639] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
[ 1090.354254] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
[ 1091.057267] CIFS: VFS: \\10.0.0.2\IPC$ validate protocol negotiate failed: -22
[ 1091.058141] CIFS: VFS: \\10.0.0.2\IPC$ reconnect tcon failed rc = -5

---

Key forensic facts from KFENCE:
- Object size: 448 bytes, cache `cifs_small_rq`
- Object lifetime: 27.5 seconds (alloc at 1059.756s, first free at 1087.241s)
- Time between frees: 0.027 seconds (deterministic, single-threaded)
- Both frees from same task (PID 1881, `rm`) — no race condition involved

  4.d. Relationship to crash_001

crash_001 detected the same double-free via KASAN. This KFENCE detection (crash_008) is an independent confirmation of the same root cause with additional forensic data. Together they provide overwhelming evidence that the bug is real, deterministic, and affecting both KASAN and KFENCE instrumentation paths.

  4.e. Suggested Fix

Null out the pointer in `SMB2_open_free()` after releasing the buffer:

---
void SMB2_open_free(struct smb_rqst *rqst)
{
    int i;
    if (rqst && rqst->rq_iov) {
        cifs_small_buf_release(rqst->rq_iov[0].iov_base);
+       rqst->rq_iov[0].iov_base = NULL;
        for (i = 1; i < rqst->rq_nvec; i++)
            if (rqst->rq_iov[i].iov_base != smb2_padding)
                kfree(rqst->rq_iov[i].iov_base);
+       rqst->rq_nvec = 0;
    }
}
---

Alternatively, add `memset(open_iov, 0, sizeof(open_iov))` at the `again` label in `smb2_unlink()`.

  5. Discovery Method and Reproduction

  5.a. Discovery

This vulnerability was discovered using ven0mfuzzer, a custom-designed MITM-based network filesystem fuzzer developed by our team. The fuzzer operates by positioning an AF_PACKET/TCP transparent proxy between a Linux kernel filesystem client (VM-A) and its server (VM-B), then mutating network protocol messages in-flight. We designed ven0mfuzzer specifically for this class of network filesystem vulnerabilities.

Following the common syzkaller practice, we submit the kernel crash trace as the primary reproduction artifact. The trace above was captured with KFENCE enabled on kernel 6.19.0.

  5.b. Reproduction Setup

---
VM-A (CIFS client) ──SMB2──► Host:44446 (MITM proxy) ──TCP──► Host:44445 ──hostfwd──► VM-B:445 (ksmbd)
---

Trigger condition: Any `unlink` operation on a CIFS mount while the MITM injects `STATUS_IO_TIMEOUT` (`0xC00000B5`) in CREATE responses followed by a forced reconnect.

---
Reported-by: ven0mfuzzer <ven0mkernelfuzzer@gmail.com>
Link: https://github.com/KernelStackFuzz/KernelStackFuzz

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [BUG] Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free
  2026-04-02 11:06 [BUG] Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free ven0mfuzzer
@ 2026-04-02 15:05 ` Paulo Alcantara
  2026-04-03 22:08 ` Steve French
  1 sibling, 0 replies; 3+ messages in thread
From: Paulo Alcantara @ 2026-04-02 15:05 UTC (permalink / raw)
  To: ven0mfuzzer, Ronnie Sahlberg, Tom Talpey, Steve French,
	Bharath SM, Shyam Prasad N
  Cc: linux-cifs, linux-kernel, samba-technical

This should be fixed by

        048efe129a29 ("smb: client: fix oops due to uninitialised var in smb2_unlink()")

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [BUG] Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free
  2026-04-02 11:06 [BUG] Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free ven0mfuzzer
  2026-04-02 15:05 ` Paulo Alcantara
@ 2026-04-03 22:08 ` Steve French
  1 sibling, 0 replies; 3+ messages in thread
From: Steve French @ 2026-04-03 22:08 UTC (permalink / raw)
  To: ven0mfuzzer
  Cc: Ronnie Sahlberg, Tom Talpey, Paulo Alcantara, Steve French,
	Bharath SM, Shyam Prasad N, linux-cifs, linux-kernel,
	samba-technical

This doesn't make sense - the suggested solution is:

   Alternatively, add `memset(open_iov, 0, sizeof(open_iov))` at the
`again` label in `smb2_unlink()`.

But it is already there.  Am I missing something? This doesn't look
real.  See line 1219 inside smb2_unlink() function in smb2inode.c

1211 again:
1212         oplock = SMB2_OPLOCK_LEVEL_NONE;
1213         server = cifs_pick_channel(tcon->ses);
1214
1215         memset(rqst, 0, sizeof(rqst));
1216         memset(resp_buftype, 0, sizeof(resp_buftype));
1217         memset(rsp_iov, 0, sizeof(rsp_iov));
1218
1219         memset(open_iov, 0, sizeof(open_iov));

On Thu, Apr 2, 2026 at 6:14 AM ven0mfuzzer <ven0mkernelfuzzer@gmail.com> wrote:
>
> Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free
>
>   1. Vulnerability Title
>
> Linux Kernel CIFS Client SMB2 Compound Request KFENCE-Confirmed Double-Free Vulnerability (ksmbd)
>
>   2. High-Level Overview
>
> This report describes the same double-free vulnerability in the Linux kernel CIFS client as crash_001 (KASAN detection), now independently confirmed by KFENCE (Kernel Electric-Fence). When the CIFS client sends a compound `CREATE + CLOSE` request (e.g., via `smb2_unlink()`), a malicious server or MITM can return `STATUS_IO_TIMEOUT` in the CREATE response, causing a retry loop. On the error-path of the retry, `SMB2_open_free()` is called a second time on an already-freed `cifs_small_rq` mempool object (448 bytes), producing a double-free.
>
> The KFENCE detection provides additional forensic detail over the KASAN report in crash_001: precise timestamps, exact object lifetime (27.5 seconds), exact slab cache name (`cifs_small_rq`), and confirmation that both frees are issued by the same task — ruling out any race condition. This is a deterministic, single-threaded double-free.
>
> This vulnerability was discovered using ven0mfuzzer, our custom-designed MITM-based network filesystem fuzzer developed by our team. Following the common syzkaller practice, we submit the kernel crash trace as the primary reproduction artifact.
>
>   3. Affected Product and Version Information
>
> Product: Linux Kernel (upstream mainline)
> Affected Component: `fs/smb/client/smb2inode.c` — `smb2_unlink()` (line 1186)
> Supporting Components:
> - `fs/smb/client/smb2pdu.c` — `SMB2_open_free()` does not null freed pointer (line 3244)
>
>   Tested Versions (confirmed vulnerable)
> - Linux kernel 6.19.0 (mainline, commit `44331bd6a610`, gcc 11.4.0, built 2026-02-13)
> - Linux kernel 6.12.74 (LTS, used in Google kernelCTF COS target)
>
>   Affected Version Range
> All kernels from approximately 6.0 through 6.19 (current mainline at time of report) with SMB2 compound replay support are believed affected.
>
>   Affected Distributions and Products
>
>  |  Vendor / Product  |  Notes  |
>  | --- | --- |
>  |  Red Hat Enterprise Linux (RHEL 9.x)  |  Ships kernels >= 5.14 with backported SMB2 compound replay  |
>  |  Ubuntu (22.04 LTS, 24.04 LTS)  |  HWE kernels 6.x include vulnerable code  |
>  |  SUSE Linux Enterprise Server (SLES 15 SP5+)  |  Kernel 6.x based  |
>  |  Debian (Bookworm, Trixie)  |  Kernels 6.1+  |
>  |  Fedora (39+)  |  Kernels 6.5+  |
>  |  Amazon Linux 2023  |  Kernel 6.1 LTS based  |
>  |  Google ChromeOS / COS  |  kernelCTF target, confirmed vulnerable on 6.12.74  |
>
>   4. Root Cause Analysis
>
>   4.a. Detailed Description
>
> This is the same root cause as crash_001: `smb2_unlink()` calls `SMB2_open_free()` twice on the same stack-local `open_iov` array pointer. The first free occurs during normal cleanup after `compound_send_recv()` returns `-EAGAIN` (due to `STATUS_IO_TIMEOUT`). The retry loop (`goto again`) reuses the same `open_iov` array without clearing it. If `SMB2_open_init()` fails on the second iteration (due to reconnect state), the `err_free` label calls `SMB2_open_free()` again on the stale pointer.
>
> The KFENCE report captures all three critical events:
>
> 1. Allocation at `smb2_unlink+0x470` — `SMB2_open_init` allocates the CREATE request buffer
> 2. First free at `smb2_unlink+0x5db` — normal cleanup after `compound_send_recv` (line 1263)
> 3. Invalid second free at `smb2_unlink+0x81c` — `err_free` label (line 1289)
>
>   4.b. Code Flow
>
> ---
> smb2_unlink()                    [fs/smb/client/smb2inode.c:1186]
>   again:
>     SMB2_open_init()             ← allocates cifs_small_rq object (448B)
>     compound_send_recv()         ← server returns STATUS_IO_TIMEOUT → -EAGAIN
>     SMB2_open_free(&rqst[0])    ← FIRST FREE (line 1263), does NOT null open_iov[0]
>     goto again
>   again:
>     memset(rqst, 0, ...)         ← clears rqst[] but NOT open_iov[] (stale pointer!)
>     SMB2_open_init()             ← fails (connection being reconnected) → rc != 0
>     goto err_free
>   err_free:
>     SMB2_open_free(&rqst[0])    ← SECOND FREE of already-freed buffer!
> ---
>
>   4.c. KFENCE Crash Trace
>
> This vulnerability was discovered by ven0mfuzzer. The following kernel trace is submitted following syzkaller's common practice of providing the raw crash trace as the primary reproduction evidence:
>
> ---
> : VFS: Signing Key   d8 d6 c0 c2 b7 56 41 83 e9 d7 b5 fd 2c df 47 62
> [ 1087.254230] CIFS: VFS: ServerIn Key  5b 78 90 2a f0 90 67 84 da 43 e8 f1 a8 43 eb 91
> [ 1087.254673] CIFS: VFS: ServerOut Key 93 3a 5d ae db 4a 4b fb 24 4b c5 b8 f9 e3 47 29
> [ 1087.258673] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
> [ 1087.259195] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
> [ 1087.259715] ==================================================================
> [ 1087.260125] BUG: KFENCE: invalid free in mempool_free+0xde/0x130
> [ 1087.260125]
> [ 1087.260556] Invalid free of 0xffff8881f5cc4e40 (in kfence-#97):
> [ 1087.260893]  mempool_free+0xde/0x130
> [ 1087.261124]  cifs_small_buf_release+0x41/0x70
> [ 1087.261392]  SMB2_open_free+0x78/0x1b0
> [ 1087.261631]  smb2_unlink+0x81c/0x8d0
> [ 1087.261870]  __cifs_unlink+0x830/0x1890
> [ 1087.262134]  vfs_unlink+0x2f0/0xbd0
> [ 1087.262369]  filename_unlinkat+0x345/0x6d0
> [ 1087.262628]  __x64_sys_unlinkat+0xc4/0x130
> [ 1087.262886]  do_syscall_64+0x111/0x690
> [ 1087.263125]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> [ 1087.263427]
> [ 1087.263531] kfence-#97: 0xffff8881f5cc4e40-0xffff8881f5cc4fff, size=448, cache=cifs_small_rq
> [ 1087.263531]
> [ 1087.264219] allocated by task 1881 on cpu 0 at 1059.756104s (27.508113s ago):
> [ 1087.264648]  mempool_alloc_noprof+0x18a/0x2c0
> [ 1087.264919]  cifs_small_buf_get+0x36/0x80
> [ 1087.265210]  __smb2_plain_req_init+0x4b/0x1140
> [ 1087.265487]  SMB2_open_init+0x1ae/0x37f0
> [ 1087.265735]  smb2_unlink+0x470/0x8d0
> [ 1087.265974]  __cifs_unlink+0x830/0x1890
> [ 1087.266226]  vfs_unlink+0x2f0/0xbd0
> [ 1087.266460]  filename_unlinkat+0x345/0x6d0
> [ 1087.266717]  __x64_sys_unlinkat+0xc4/0x130
> [ 1087.266975]  do_syscall_64+0x111/0x690
> [ 1087.267214]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> [ 1087.267514]
> [ 1087.267618] freed by task 1881 on cpu 0 at 1087.241106s (0.026511s ago):
> [ 1087.268109]  mempool_free+0xde/0x130
> [ 1087.268352]  cifs_small_buf_release+0x41/0x70
> [ 1087.268620]  SMB2_open_free+0x78/0x1b0
> [ 1087.268858]  smb2_unlink+0x5db/0x8d0
> [ 1087.269091]  __cifs_unlink+0x830/0x1890
> [ 1087.269293]  vfs_unlink+0x2f0/0xbd0
> [ 1087.269481]  filename_unlinkat+0x345/0x6d0
> [ 1087.269687]  __x64_sys_unlinkat+0xc4/0x130
> [ 1087.269895]  do_syscall_64+0x111/0x690
> [ 1087.270086]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> [ 1087.270327]
> [ 1087.270417] CPU: 0 UID: 0 PID: 1881 Comm: rm Tainted: G    B               6.19.0-g44331bd6a610-dirty #5 PREEMPT(lazy)
> [ 1087.270900] Tainted: [B]=BAD_PAGE
> [ 1087.271061] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
> [ 1087.271561] ==================================================================
> [ 1087.723901] CIFS: VFS: \\10.0.0.2 RFC 1002 unknown response type 0x8
> [ 1087.739764] CIFS: VFS: \\10.0.0.2\IPC$ validate protocol negotiate failed: -11
> [ 1087.740391] CIFS: VFS: \\10.0.0.2\IPC$ reconnect tcon failed rc = -5
> [ 1087.746271] CIFS: VFS: generate_smb3signingkey: dumping generated AES session keys
> [ 1087.746842] CIFS: VFS: Session Id    02 00 00 00 00 00 00 00
> [ 1087.747238] CIFS: VFS: Cipher type   1
> [ 1087.747464] CIFS: VFS: Session Key   71 85 72 ad 7c b4 da e7 cf dc c0 ae 3a 07 98 19
> [ 1087.747888] CIFS: VFS: Signing Key   88 3f d1 03 8b 13 17 97 88 be 52 23 9b 8d a9 ed
> [ 1087.748463] CIFS: VFS: ServerIn Key  0e 28 bd af 95 9d 5d e4 34 0a d5 de a6 9a 74 0d
> [ 1087.749077] CIFS: VFS: ServerOut Key ba a1 76 7c c0 b9 32 db 27 09 85 1a e7 7d cf 65
> [ 1087.754602] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -13
> [ 1087.755289] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
> [ 1087.758970] CIFS: VFS: smb2_get_data_area_len: invalid data area (off=10608 len=24)
> [ 1087.759770] CIFS: VFS: \\10.0.0.2\fuzzshare Malformed ioctl resp: len 24 offset 10608
> [ 1087.760271] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -5
> [ 1087.760742] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
> [ 1087.764494] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
> [ 1087.765178] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
> [ 1088.197368] CIFS: VFS: Bad protocol string signature header 420053fe
> [ 1088.198145] CIFS: VFS: Bad SMB detected. The Mid=16
> [ 1088.198652] 00000000: 420053fe 00010040 00000000 000a0005  .S.B@...........
> [ 1088.199364] 00000010: 00000001 00000000 00000010 00000000  ................
> [ 1088.200070] 00000020: 00000776 00000004 00000002 00000002  v...............
> [ 1088.459625] CIFS: VFS: \\10.0.0.2 RFC 1002 unknown response type 0x42
> [ 1089.503269] CIFS: VFS: generate_smb3signingkey: dumping generated AES session keys
> [ 1089.503705] CIFS: VFS: Session Id    02 00 00 00 00 00 00 00
> [ 1089.504013] CIFS: VFS: Cipher type   1
> [ 1089.504229] CIFS: VFS: Session Key   d6 56 c8 0b 7a 8f 2c 81 4a 9a 16 b8 ef a6 df 50
> [ 1089.504575] CIFS: VFS: Signing Key   b6 36 17 ad 2f 1d d5 d6 21 0a 98 37 50 9a 31 08
> [ 1089.504914] CIFS: VFS: ServerIn Key  b6 c4 17 a9 16 ed 60 72 14 1b 64 6b d5 20 5f f2
> [ 1089.505485] CIFS: VFS: ServerOut Key e1 8c 7f af 9e 04 ed 2c 67 47 63 68 e4 eb 9e 2b
> [ 1089.718373] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
> [ 1089.719252] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
> [ 1090.142104] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -5
> [ 1090.142986] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
> [ 1090.353639] CIFS: VFS: \\10.0.0.2\fuzzshare validate protocol negotiate failed: -22
> [ 1090.354254] CIFS: VFS: \\10.0.0.2\fuzzshare reconnect tcon failed rc = -5
> [ 1091.057267] CIFS: VFS: \\10.0.0.2\IPC$ validate protocol negotiate failed: -22
> [ 1091.058141] CIFS: VFS: \\10.0.0.2\IPC$ reconnect tcon failed rc = -5
>
> ---
>
> Key forensic facts from KFENCE:
> - Object size: 448 bytes, cache `cifs_small_rq`
> - Object lifetime: 27.5 seconds (alloc at 1059.756s, first free at 1087.241s)
> - Time between frees: 0.027 seconds (deterministic, single-threaded)
> - Both frees from same task (PID 1881, `rm`) — no race condition involved
>
>   4.d. Relationship to crash_001
>
> crash_001 detected the same double-free via KASAN. This KFENCE detection (crash_008) is an independent confirmation of the same root cause with additional forensic data. Together they provide overwhelming evidence that the bug is real, deterministic, and affecting both KASAN and KFENCE instrumentation paths.
>
>   4.e. Suggested Fix
>
> Null out the pointer in `SMB2_open_free()` after releasing the buffer:
>
> ---
> void SMB2_open_free(struct smb_rqst *rqst)
> {
>     int i;
>     if (rqst && rqst->rq_iov) {
>         cifs_small_buf_release(rqst->rq_iov[0].iov_base);
> +       rqst->rq_iov[0].iov_base = NULL;
>         for (i = 1; i < rqst->rq_nvec; i++)
>             if (rqst->rq_iov[i].iov_base != smb2_padding)
>                 kfree(rqst->rq_iov[i].iov_base);
> +       rqst->rq_nvec = 0;
>     }
> }
> ---
>
> Alternatively, add `memset(open_iov, 0, sizeof(open_iov))` at the `again` label in `smb2_unlink()`.
>
>   5. Discovery Method and Reproduction
>
>   5.a. Discovery
>
> This vulnerability was discovered using ven0mfuzzer, a custom-designed MITM-based network filesystem fuzzer developed by our team. The fuzzer operates by positioning an AF_PACKET/TCP transparent proxy between a Linux kernel filesystem client (VM-A) and its server (VM-B), then mutating network protocol messages in-flight. We designed ven0mfuzzer specifically for this class of network filesystem vulnerabilities.
>
> Following the common syzkaller practice, we submit the kernel crash trace as the primary reproduction artifact. The trace above was captured with KFENCE enabled on kernel 6.19.0.
>
>   5.b. Reproduction Setup
>
> ---
> VM-A (CIFS client) ──SMB2──► Host:44446 (MITM proxy) ──TCP──► Host:44445 ──hostfwd──► VM-B:445 (ksmbd)
> ---
>
> Trigger condition: Any `unlink` operation on a CIFS mount while the MITM injects `STATUS_IO_TIMEOUT` (`0xC00000B5`) in CREATE responses followed by a forced reconnect.
>
> ---
> Reported-by: ven0mfuzzer <ven0mkernelfuzzer@gmail.com>
> Link: https://github.com/KernelStackFuzz/KernelStackFuzz
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-03 22:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-02 11:06 [BUG] Linux Kernel CIFS Client SMB2_open_free KFENCE Double-Free ven0mfuzzer
2026-04-02 15:05 ` Paulo Alcantara
2026-04-03 22:08 ` Steve French

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox