Skip to content

[LTS 9.2] smb: client: fix OOBs when building SMB2_IOCTL request #431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 23, 2025

Conversation

pvts-mat
Copy link
Contributor

[LTS 9.2]
CVE-2024-50151
VULN-8636

Problem

https://access.redhat.com/security/cve/CVE-2024-50151

A flaw was found in the cifs module in the Linux kernel. When building SMB2_IOCTL requests using encryption, either enforced by the server or using the 'seal' mount option, an out-of-bounds write can be triggered when the user passes an input buffer greater than 328 bytes, resulting in memory corruption and a kernel crash.

Background

CIFS (Common Internet File System) is basically a different name for Microsoft's SMB (Server Message Block) protocol, allowing for sharing files and printers on the network. Functionality-wise CIFS is the same as more Linux-native NFS system. From the practical perspective, using the CIFS module boils down to mounting appropriately addressed remote "share" at a local directory (hence the "'seal' mount option" mentioned in the CVE description).

Applicability: yes

The original mainline fix is contained in 1ab6032. The affected file is fs/smb/client/smb2pdu.c. For the LTS 9.2 version this corresponds to the fs/cifs/smb2pdu.c file, which was moved to fs/smb/client/ in 38c8a9a. The file is compiled into the kernel with the CONFIG_CIFS option:

obj-$(CONFIG_CIFS) += cifs.o
cifs-y := trace.o cifsfs.o cifs_debug.o connect.o dir.o file.o \
inode.o link.o misc.o netmisc.o smbencrypt.o transport.o \
cached_dir.o cifs_unicode.o nterr.o cifsencrypt.o \
readdir.o ioctl.o sess.o export.o unc.o winucase.o \
smb2ops.o smb2maperror.o smb2transport.o \
smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \
dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o
.

The option is enabled in ciqlts9_2:

$ grep 'CONFIG_CIFS\b' configs/*.config

configs/kernel-aarch64-64k-debug-rhel.config:CONFIG_CIFS=m
configs/kernel-aarch64-64k-rhel.config:CONFIG_CIFS=m
configs/kernel-aarch64-debug-rhel.config:CONFIG_CIFS=m
configs/kernel-aarch64-rhel.config:CONFIG_CIFS=m
configs/kernel-ppc64le-debug-rhel.config:CONFIG_CIFS=m
configs/kernel-ppc64le-rhel.config:CONFIG_CIFS=m
configs/kernel-s390x-debug-rhel.config:CONFIG_CIFS=m
configs/kernel-s390x-rhel.config:CONFIG_CIFS=m
configs/kernel-s390x-zfcpdump-rhel.config:CONFIG_CIFS=m
configs/kernel-x86_64-debug-rhel.config:CONFIG_CIFS=m
configs/kernel-x86_64-rhel.config:CONFIG_CIFS=m

The e77fe73 commit identified in 1ab6032 as introducing the bug is present in ciqlts9_2's history of the module (specifically the files fs/cifs/{smb2inode.c,smb2ops.c,smb2proto.h}). The fixing 1ab6032 commit was not backported to ciqlts9_2.

Solution

An official stable release backport e07d05b to 5.15 was used to cherry-pick onto ciqlts9_2. It applies cleanly, unlike the mainline fix, as 5.15 uses the same CIFS module's files layout as ciqlts9_2.

kABI check: passed

DEBUG=1 CVE=CVE-2024-50151 ./ninja.sh _kabi_checked__x86_64--test--ciqlts9_2-CVE-2024-50151

[0/1] Check ABI of kernel [ciqlts9_2-CVE-2024-50151]
++ uname -m
+ python3 /data/src/ctrliq-github/kernel-dist-git-el-9.2/SOURCES/check-kabi -k /data/src/ctrliq-github/kernel-dist-git-el-9.2/SOURCES/Module.kabi_x86_64 -s vms/x86_64--build--ciqlts9_2/build_files/kernel-src-tree-ciqlts9_2-CVE-2024-50151/Module.symvers
kABI check passed
+ touch state/kernels/ciqlts9_2-CVE-2024-50151/x86_64/kabi_checked

Boot test: passed

See Specific tests for the implied boot test passing.

Kselftests: passed relative

No selftests were found for the CIFS module. The general selftsts were run nevertheless, mainly as part of the effort to debug the kernels 9.2 and 9.4 instability issue.

Coverage

bpf (except test_kmod.sh, test_xsk.sh, test_progs, test_progs-no_alu32, test_sockmap), breakpoints (except step_after_suspend_test), capabilities, cgroup (except test_freezer, test_memcontrol), clone3, core, cpu-hotplug, cpufreq, drivers/dma-buf, drivers/net/bonding, drivers/net/team, filesystems/binderfs, firmware, fpu, ftrace, futex, gpio, intel_pstate, ipc, ir, kcmp, kexec, kvm, landlock, lib, livepatch, membarrier, memfd, memory-hotplug, mincore, mount, mqueue, nci, net/forwarding (except sch_tbf_prio.sh, mirror_gre_vlan_bridge_1q.sh, dual_vxlan_bridge.sh, ipip_hier_gre_keys.sh, vxlan_bridge_1d_ipv6.sh, sch_tbf_root.sh, sch_tbf_ets.sh, sch_red.sh, tc_actions.sh, mirror_gre_bridge_1d_vlan.sh, tc_police.sh, q_in_vni.sh, sch_ets.sh, gre_inner_v6_multipath.sh), net/mptcp (except mptcp_join.sh, simult_flows.sh, userspace_pm.sh), net (except xfrm_policy.sh, reuseport_addr_any.sh, udpgro_fwd.sh, gro.sh, txtimestamp.sh, fib_nexthops.sh, ip_defrag.sh, udpgso_bench.sh), netfilter (except nft_trans_stress.sh), nsfs, openat2, pid_namespace, pidfd, proc (except proc-pid-vm, proc-uptime-001), pstore, ptrace, rlimits, rseq, seccomp, sgx, sigaltstack, size, splice, static_keys, syscall_user_dispatch, tc-testing, tdx, timens, timers (except raw_skew), tmpfs, tpm2, vDSO, vm, x86, zram

Reference

kselftests–ciqlts9_2–run1.log

Patch

kselftests–ciqlts9_2-CVE-2024-50151–run2.log
kselftests–ciqlts9_2-CVE-2024-50151–run1.log

Comparison

The reference and patch results are the same.

$ ktests.xsh diff -d kselftests*.log

Column    File
--------  ----------------------------------------------
Status0   kselftests--ciqlts9_2--run1.log
Status1   kselftests--ciqlts9_2-CVE-2024-50151--run1.log
Status2   kselftests--ciqlts9_2-CVE-2024-50151--run2.log

Specific tests: passed

The 1ab6032 commit mentions a way to replicate the bug

mount.cifs //srv/share /mnt -o ...,seal
ln -s $(perl -e "print('a')for 1..1024") /mnt/link

An attempt was made to replicate the bug on ciqlts9_2 with KASAN enabled, but it failed - no KASAN errors were obtained and the symlink creation worked fine. Perhaps it had to do with the SMB share being hosted on the very same machine where it was mounted, but setting up a "proper" samba share were dropped after a couple of unsuccesfull attempts at getting rid of NT_STATUS_CONNECTION_REFUSED error. The same test was repeated on the patched kernel with the same result. At the very least it shows that the CIFS module remains functional.

The steps setting up encrypted samba share were as follows:

sudo dnf --color=never install cifs-utils samba -y
mkdir -p /sambashare
chmod 2770 /sambashare/
semanage fcontext -at samba_share_t '/sambashare(/.*)?'
restorecon -vvFR /sambashare
groupadd sales
chgrp sales /sambashare/
useradd -s /sbin/nologin -G sales calvin
smbpasswd -a calvin
echo -e '
[global]
\tworkgroup = SAMBA
\tsecurity = user

\tpassdb backend = tdbsam

\tprinting = cups
\tprintcap name = cups
\tload printers = yes
\tcups options = raw

[smbshare]
\tpath = /sambashare
\twrite list = @sales
' > /etc/samba/smb.conf
SYSTEMD_COLORS=0 systemctl --no-pager restart smb
SYSTEMD_COLORS=0 systemctl --no-pager restart nmb
echo "username=calvin
password=redhat
" > smb-multiuser.txt
mkdir sales
sudo mount.cifs //localhost/smbshare /home/pvts/sales -o credentials=/home/pvts/smb-multiuser.txt,multiuser,sec=ntlmssp,mfsymlinks,seal
ln -s $(perl -e "print('a')for 1..1024") /home/pvts/sales/link

reference-replication.log
patch-replication.log

jira VULN-8636
cve CVE-2024-50151
commit-author Paulo Alcantara <pc@manguebit.com>
commit 1ab6032
upstream-diff used linux-stable LT-5.15 sha e07d05b

[ Upstream commit 1ab6032 ]

When using encryption, either enforced by the server or when using
'seal' mount option, the client will squash all compound request buffers
down for encryption into a single iov in smb2_set_next_command().

SMB2_ioctl_init() allocates a small buffer (448 bytes) to hold the
SMB2_IOCTL request in the first iov, and if the user passes an input
buffer that is greater than 328 bytes, smb2_set_next_command() will
end up writing off the end of @rqst->iov[0].iov_base as shown below:

  mount.cifs //srv/share /mnt -o ...,seal
  ln -s $(perl -e "print('a')for 1..1024") /mnt/link

  BUG: KASAN: slab-out-of-bounds in
  smb2_set_next_command.cold+0x1d6/0x24c [cifs]
  Write of size 4116 at addr ffff8881148fcab8 by task ln/859

  CPU: 1 UID: 0 PID: 859 Comm: ln Not tainted 6.12.0-rc3 ctrliq#1
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
  1.16.3-2.fc40 04/01/2014
  Call Trace:
   <TASK>
   dump_stack_lvl+0x5d/0x80
   ? smb2_set_next_command.cold+0x1d6/0x24c [cifs]
   print_report+0x156/0x4d9
   ? smb2_set_next_command.cold+0x1d6/0x24c [cifs]
   ? __virt_addr_valid+0x145/0x310
   ? __phys_addr+0x46/0x90
   ? smb2_set_next_command.cold+0x1d6/0x24c [cifs]
   kasan_report+0xda/0x110
   ? smb2_set_next_command.cold+0x1d6/0x24c [cifs]
   kasan_check_range+0x10f/0x1f0
   __asan_memcpy+0x3c/0x60
   smb2_set_next_command.cold+0x1d6/0x24c [cifs]
   smb2_compound_op+0x238c/0x3840 [cifs]
   ? kasan_save_track+0x14/0x30
   ? kasan_save_free_info+0x3b/0x70
   ? vfs_symlink+0x1a1/0x2c0
   ? do_symlinkat+0x108/0x1c0
   ? __pfx_smb2_compound_op+0x10/0x10 [cifs]
   ? kmem_cache_free+0x118/0x3e0
   ? cifs_get_writable_path+0xeb/0x1a0 [cifs]
   smb2_get_reparse_inode+0x423/0x540 [cifs]
   ? __pfx_smb2_get_reparse_inode+0x10/0x10 [cifs]
   ? rcu_is_watching+0x20/0x50
   ? __kmalloc_noprof+0x37c/0x480
   ? smb2_create_reparse_symlink+0x257/0x490 [cifs]
   ? smb2_create_reparse_symlink+0x38f/0x490 [cifs]
   smb2_create_reparse_symlink+0x38f/0x490 [cifs]
   ? __pfx_smb2_create_reparse_symlink+0x10/0x10 [cifs]
   ? find_held_lock+0x8a/0xa0
   ? hlock_class+0x32/0xb0
   ? __build_path_from_dentry_optional_prefix+0x19d/0x2e0 [cifs]
   cifs_symlink+0x24f/0x960 [cifs]
   ? __pfx_make_vfsuid+0x10/0x10
   ? __pfx_cifs_symlink+0x10/0x10 [cifs]
   ? make_vfsgid+0x6b/0xc0
   ? generic_permission+0x96/0x2d0
   vfs_symlink+0x1a1/0x2c0
   do_symlinkat+0x108/0x1c0
   ? __pfx_do_symlinkat+0x10/0x10
   ? strncpy_from_user+0xaa/0x160
   __x64_sys_symlinkat+0xb9/0xf0
   do_syscall_64+0xbb/0x1d0
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
  RIP: 0033:0x7f08d75c13bb

	Reported-by: David Howells <dhowells@redhat.com>
Fixes: e77fe73 ("cifs: we can not use small padding iovs together with encryption")
	Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
	Signed-off-by: Steve French <stfrench@microsoft.com>
	Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit e07d05b)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
@PlaidCat
Copy link
Collaborator

Kselftests: passed relative

No selftests were found for the CIFS module. The general selftsts were run nevertheless, mainly as part of the effort to debug the kernels 9.2 and 9.4 instability issue.

To clarify these are instabilities during some kselftests which we know sometimes are not entirely stable run to run, but it is worth investigating. Thank You

Copy link
Collaborator

@PlaidCat PlaidCat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Thank You for the run down and using the Upsteram Sha in the commit message for the CIQ header

Copy link

@thefossguy-ciq thefossguy-ciq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚤

@PlaidCat PlaidCat merged commit 5808c66 into ctrliq:ciqlts9_2 Jul 23, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants