Blog
Blog

[CVE-2026-43490] Linux Kernel: ksmbd: Remote Memory Corruption via ACL Inheritance

2026-05-15

TL;DR

Linux ksmbd had a remote memory corruption bug in the ACL inheritance path. A remote SMB client that can create a directory, set a crafted DACL on it, and create a child entry below it can make ksmbd inherit an ACE whose SID advertises an inflated num_subauth value.

The vulnerable path reads and sizes the SID inconsistently. In my KASAN reproduction, a malformed inheritable ACE with num_subauth = 255 and only two serialized sub-authority values caused a heap out-of-bounds read followed by heap corruption / slab-use-after-free writes in the kernel.



Target

Item Value
Vendor Linux
Product Linux kernel, ksmbd
CVE CVE-2026-43490
CWE CWE-125: Out-of-bounds Read
CVSS (Assessed) v3.1: 8.8 High / v4.0: 8.7 High
Upstream Fixed Commit 996454bc0da8 (ksmbd: validate inherited ACE SID length)
Fixed Versions 6.12.88, 6.18.30, 7.0.7, and 7.1-rc3+
Primary Component fs/smb/server/smbacl.c
Initial Report Tree 27d128c1cff6, checked on 2026-04-25 JST with KASAN enabled

The CVE description summarizes the issue as a remote memory corruption vulnerability in the ACL inheritance path that can be triggered by setting a crafted DACL through SMB2_SET_INFO and then creating child entries.



Overview

The bug is reached when a parent directory already has a security.NTACL xattr. When a child file or directory is created, ksmbd calls smb_inherit_dacl() to copy inheritable ACEs from the parent DACL into the child security descriptor.

Remote SMB client Create a parent directory and set a crafted DACL through SMB2_SET_INFO(SECURITY).
security.NTACL xattr The parent directory stores an inheritable ACE with a malformed SID.
Child entry creation ksmbd enters the DACL inheritance path for the new child object.
smb_inherit_dacl() The inherited ACE SID length is trusted across copy and sizing paths.
Kernel memory corruption KASAN reports heap out-of-bounds reads and slab-use-after-free writes.

The relevant malformed object is an inheritable ACE whose SID header says that it contains many sub-authority values, but whose serialized ACE body does not actually contain those values. In the reproducer, the SID declares num_subauth = 255 while the serialized SID contains only two sub-authorities.

Non-inheritable ACEs do not reach the vulnerable copy path. The malformed ACE must pass the inheritance gate in smb_inherit_dacl().


Root Cause

1. The inherited ACE SID length was not fully validated

smb_inherit_dacl() walked the parent DACL loaded from the security descriptor xattr. It checked that each ACE had enough space for the fixed SID header, but it did not verify that the variable-length SID described by sid.num_subauth was fully contained in the ACE.

vulnerable shape, simplified
if (pace_size < offsetof(struct smb_ace, sid) + CIFS_SID_BASE_SIZE)
    break;

/* Missing: does pace_size include sid.num_subauth * sizeof(__le32)? */

That left later SID consumers operating on a source SID whose declared length and physical buffer length did not match.

SID header num_subauth = 255
sub_auth[0] present
sub_auth[1] present
sub_auth[2] ... sub_auth[254] not present in the ACE buffer

2. smb_copy_sid() bounded the destination, not the source

smb_copy_sid() clamps the destination SID count to SID_MAX_SUB_AUTHORITIES. That prevents an oversized destination SID, but it does not prove that the source buffer contains that many sub-authority entries.

With a source SID declaring num_subauth = 255, the destination count becomes 15, and the copy path can read fifteen sub-authority values from a source SID that physically contains only two. In my reproduction, this produced a 52-byte heap out-of-bounds read past the decoded NTACL buffer.

3. smb_set_ace() used the unchecked source SID count for sizing

After copying the SID, smb_set_ace() computed the inherited ACE size using the original source sid->num_subauth value instead of the copied, clamped destination SID count.

old size computation, simplified
smb_copy_sid(&ace->sid, sid);
ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 +
                        (sid->num_subauth * 4));

For sid->num_subauth = 255, the resulting ACE size is 1036 bytes. The temporary inherited ACE buffer in smb_inherit_dacl() was much smaller than that attacker-influenced stride, so subsequent ACE writes could land outside the intended allocation.



Impact and Preconditions

Dimension Description
Attack Vector Network, through SMB
Required Privilege A session that can create entries and set a DACL on the chosen parent directory
Observed Result KASAN heap out-of-bounds read and slab-use-after-free reports in the ksmbd inheritance path
CVSS Basis Network attack vector, low privileges, no user interaction, and kernel heap memory corruption with high confidentiality, integrity, and availability impact assumed
Practical Impact Kernel instability or denial of service; for an authenticated low-privileged SMB user who can set DACLs on a parent directory, reliable exploitation could result in kernel privilege escalation

The issue is reachable when ksmbd serves a share where the backing filesystem supports security.* xattrs and the attacker can issue SMB2_SET_INFO(SECURITY) / WRITE_DAC on a parent directory that they can later create children under.

This should be treated as remote kernel memory corruption in ksmbd, not as a harmless ACL parser discrepancy.


Reproduction Summary

The validation trigger used a malformed three-ACE DACL:

  1. ACE 0 is a direct Everyone ACE so the directory remains accessible.
  2. ACE 1 is inheritable and contains a malformed SID with num_subauth = 255 but only two serialized sub-authorities.
  3. ACE 2 repeats the malformed inheritable ACE.

The client-side sequence was to create or open a parent directory, set the crafted self-relative security descriptor on that directory, verify the stored ACL with QUERY_INFO, and finally create a child entry under that parent to trigger ACL inheritance.

Observed KASAN result

In my run, KASAN produced 47 total reports: 15 slab-out-of-bounds reports and 32 slab-use-after-free reports.

representative read-side report
BUG: KASAN: slab-out-of-bounds in smb_inherit_dacl+0x164d/0x1fb0
Read of size 4 at addr ffff88800a458360 by task kworker/1:1/43
The buggy address is located 0 bytes to the right of allocated 96-byte region
representative write-side report
BUG: KASAN: slab-use-after-free in smb_inherit_dacl+0x18ba/0x1fb0
Write of size 1 at addr ffff8880098e040c by task kworker/1:1/43


Fix

The upstream fix validates the inherited parent ACE SID count and SID length before using the SID. It also computes the inherited ACE size from the copied destination SID, so the size matches the bounded SID that will actually be stored.

fixed size computation, simplified
smb_copy_sid(&ace->sid, sid);
ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 +
                        (ace->sid.num_subauth * 4));

The patch also adds size accumulation checks around inherited ACE construction and security descriptor allocation, rejecting the inherited DACL if the computed sizes overflow the ACL or allocation bounds.

Fixed by torvalds/linux@996454bc0da8, committed by Steve French on 2026-05-02 UTC.


Kernel Release History

The kernel-side history is listed here as fixed versions, fix commits, and authoritative release links. The full kernel ChangeLogs are useful as source evidence, but embedding them in full would make the write-up harder to audit.

Kernel Line Fixed Version Fix Commit Release Evidence
6.12.y 6.12.88 47c6e37a77b1 ChangeLog-6.12.88
6.18.y 6.18.30 1aa60fea7f63 ChangeLog-6.18.30
7.0.y 7.0.7 c1d95c995d5b ChangeLog-7.0.7
mainline / 7.1-rc 7.1-rc3 and later 996454bc0da8 CVE record
The stable ChangeLog entries point back to upstream commit 996454bc0da8, so these are backports of the same fix rather than separate vulnerability variants.


Timeline

Date Event
2026-04-25 JST Initial report sent to the ksmbd / Linux kernel security contacts with KASAN results and source links.
2026-04-28 JST Patch resent as a git format-patch attachment after the first inline patch was mangled by the mail client.
2026-05-01 Namjae Jeon confirmed that the patch looked good and had been applied to #ksmbd-for-next-next.
2026-05-02 UTC Fix commit 996454bc0da8 authored by Shota Zaizen and committed by Steve French.
2026-05-14 UTC The fix appeared in the 6.12.88, 6.18.30, and 7.0.7 stable release ChangeLogs on kernel.org.
2026-05-15 UTC CVE-2026-43490 published and announced on linux-cve-announce.
2026-05-15 JST This public write-up added.


References

1 object(s) selected 1.44 MB
Blog
12:00 PM