From: Michael Bommarito <michael.bommarito@gmail.com>
To: linux-cifs@vger.kernel.org, Namjae Jeon <linkinjeon@kernel.org>,
Steve French <smfrench@gmail.com>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>,
Tom Talpey <tom@talpey.com>,
stable@vger.kernel.org
Subject: [PATCH 0/3] ksmbd: harden IPC response arithmetic and ACE walk
Date: Tue, 14 Apr 2026 15:15:30 -0400 [thread overview]
Message-ID: <20260414191533.1467353-1-michael.bommarito@gmail.com> (raw)
Hi,
Three ksmbd patches: two hardening fixes for the kernel <-> mountd
IPC arithmetic, plus one authenticated OOB-read fix in the DACL
ACE walker. All three reproduced under UML + KASAN on v7.0-rc7.
Patch 3 reproduces end-to-end over loopback SMB2 from a guest
client against UML ksmbd + ksmbd.mountd:
pre-fix:
BUG: KASAN: slab-out-of-bounds in compare_sids+0x2b1/0x440
compare_sids
smb_check_perm_dacl+0x4fe/0x11a0
smb2_open+0x4eb2/0xad50
handle_ksmbd_work+0x3d3/0x1140
"The buggy address is located 4 bytes to the right of
allocated 32-byte region" with the allocation trace pointing
at ndr_decode_v4_ntacl() reading the stored xattr.
post-fix:
CREATE returns STATUS_ACCESS_DENIED; no KASAN splat; granted
bits stay at 0 because the tightened bound rejects ace_size=4
before compare_sids is called.
Patches 1 and 2 reproduced with in-kernel synthetic triggers that
hand ipc_validate_msg() a response with a wrap-matching size:
patch 1 (RPC_REQUEST payload_sz):
pre-fix returns 0 (u32 wrap bypass)
post-fix returns -EINVAL (payload_sz > KSMBD_IPC_MAX_PAYLOAD)
patch 1 + 2 (LOGIN_REQUEST_EXT ngroups=-1):
pre-fix returns 0 (signed->size_t wrap matches msg_sz)
post-fix returns -EINVAL (explicit ngroups<0 gate)
Same threat model as the earlier hardening commits aab98e2dbd64
("ksmbd: fix integer overflows on 32 bit systems") and 6f40e50ceb99
("ksmbd: transport_ipc: validate payload size before reading
handle"): the kernel should not trust arithmetic on attacker-
controlled fields even when those fields come from a cooperating
root daemon or an authenticated client writing an xattr.
Patch 1/3 caps the attacker-controlled fields in ipc_validate_msg()
against the existing KSMBD_IPC_MAX_PAYLOAD / NGROUPS_MAX bounds
before they feed the size-computation arithmetic. Three cases:
- KSMBD_EVENT_RPC_REQUEST: sizeof(struct) + resp->payload_sz
(__u32) can wrap in unsigned int; downstream consumer at
smb2pdu.c:6742 uses rpc_resp->payload_sz for a memcpy. Cap
payload_sz against KSMBD_IPC_MAX_PAYLOAD, matching the
request-side cap in aab98e2dbd64.
- KSMBD_EVENT_SHARE_CONFIG_REQUEST: sizeof(struct) +
resp->payload_sz same class; same cap.
- KSMBD_EVENT_LOGIN_REQUEST_EXT: resp->ngroups is __s32 signed,
so the existing > NGROUPS_MAX comparison at user_config.c:59
misses negative values, and the mul sizeof(gid_t) mixes signed
and size_t in a surprising way. Reject ngroups outside the
signed [0, NGROUPS_MAX] range up front.
Patch 2/3 fixes user_config.c so ksmbd_alloc_user() also rejects
negative ngroups explicitly, independent of ipc_validate_msg.
Patch 3/3 tightens bounds checking in smb_check_perm_dacl()'s two
ACE-walk loops. Today they only require the 4-byte ACE header to
fit in the remaining DACL buffer; an attacker-declared ace->size
of 4 passes both guards, after which the loop reads access_req
(offset 4) and ace->sid (offset 8+) past the real buffer.
parse_sec_desc() already performs an equivalent check; this patch
brings smb_check_perm_dacl() up to the same bar.
Practical exploitation of patches 1-2 is narrow: the wrap-bypass
requires ksmbd.mountd to send a response crafted around the wrapped
size while preserving consistent field values, and the downstream
kvmalloc almost always fails for u32-wrap sizes. Patch 3 is
reachable post-auth by any client that can SET an ACL and then
OPEN the affected file.
The patch 3 exploit chain is authenticated but otherwise untrusted:
guest session -> TREE_CONNECT -> CREATE evil.dat -> SET_INFO with a
crafted security descriptor (one ACE with size=4) -> close -> re-open
the file, which triggers smb_check_perm_dacl() in smb2_open(). The
malformed SD is accepted by SET_INFO without validation on the write
side; parsing happens on the next open.
Instrumentation, triggers, client, and both console logs are
available on request.
Michael Bommarito (3):
ksmbd: cap response sizes in ipc_validate_msg()
ksmbd: reject negative ngroups in ksmbd_alloc_user()
ksmbd: require minimum ACE size in smb_check_perm_dacl()
fs/smb/server/mgmt/user_config.c | 2 +-
fs/smb/server/smbacl.c | 17 +++++++++++++----
fs/smb/server/transport_ipc.c | 42 +++++++++++++++++++++++++++++-----
3 files changed, 49 insertions(+), 12 deletions(-)
--
2.53.0
next reply other threads:[~2026-04-14 19:15 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-14 19:15 Michael Bommarito [this message]
2026-04-14 19:15 ` [PATCH 1/3] ksmbd: cap response sizes in ipc_validate_msg() Michael Bommarito
2026-04-15 2:00 ` Namjae Jeon
2026-04-15 2:35 ` Michael Bommarito
2026-04-15 4:22 ` Namjae Jeon
2026-04-14 19:15 ` [PATCH 2/3] ksmbd: reject negative ngroups in ksmbd_alloc_user() Michael Bommarito
2026-04-15 2:05 ` Namjae Jeon
2026-04-15 2:35 ` Michael Bommarito
2026-04-15 4:31 ` Namjae Jeon
2026-04-14 19:15 ` [PATCH 3/3] ksmbd: require minimum ACE size in smb_check_perm_dacl() Michael Bommarito
2026-04-15 11:24 ` [PATCH v2 0/2] ksmbd: harden ipc_validate_msg() and smb_check_perm_dacl() Michael Bommarito
2026-04-15 11:25 ` [PATCH v2 1/2] ksmbd: validate response sizes in ipc_validate_msg() Michael Bommarito
2026-04-15 11:25 ` [PATCH v2 2/2] ksmbd: require minimum ACE size in smb_check_perm_dacl() Michael Bommarito
2026-04-16 0:07 ` [PATCH v2 0/2] ksmbd: harden ipc_validate_msg() and smb_check_perm_dacl() Namjae Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260414191533.1467353-1-michael.bommarito@gmail.com \
--to=michael.bommarito@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=senozhatsky@chromium.org \
--cc=smfrench@gmail.com \
--cc=stable@vger.kernel.org \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox