From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Namjae Jeon <linkinjeon@kernel.org>,
Steve French <stfrench@microsoft.com>,
Sasha Levin <sashal@kernel.org>,
smfrench@gmail.com, linux-cifs@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.18-5.15] ksmbd: validate SID namespace before mapping IDs
Date: Mon, 31 Aug 2026 09:27:13 -0400 [thread overview]
Message-ID: <20260831133314.4125787-405-sashal@kernel.org> (raw)
In-Reply-To: <20260831133314.4125787-1-sashal@kernel.org>
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit fbe0bb2b75eb3c61e8464486506253d1b471240b ]
sid_to_id() currently treats the last subauthority of any owner or group
SID as a Unix uid or gid. For example, this maps Everyone (S-1-1-0) to
uid 0 and BUILTIN\Users (S-1-5-32-545) to gid 545.
When an SMB2 CREATE security descriptor contains those SIDs, ksmbd
attempts to change the newly created file to the bogus Unix ownership.
notify_change() then returns -EPERM, which makes smb2.create.aclfile fail
with NT_STATUS_SHARING_VIOLATION.
Validate the SID prefix before extracting its RID. Only server-domain
owner SIDs and S-1-22-2 Unix group SIDs have local ID representations.
Treat other valid Windows SIDs as unmapped so their original values can
still be preserved in the NT ACL xattr.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `ksmbd: validate SID namespace before
mapping IDs`
**Local tree:** Linux 6.18.44 (`v6.18.44-1-g2736c32da98b9`)
**Candidate commit:** `fbe0bb2b75eb3` (mainline 7.2-rc2; **not** in
current HEAD history)
**Bug status in this tree:** Present — `sid_to_id()` lacks SID prefix
validation
---
## PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1 — Subject line**
Record: `[ksmbd] [validate] validate SID namespace before mapping IDs` —
ACL/SID correctness fix in the SMB server.
**Step 1.2 — Tags**
Record:
- `Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>` (ksmbd
maintainer)
- `Signed-off-by: Steve French <stfrench@microsoft.com>` (CIFS/SMB
maintainer)
- No `Fixes:`, `Reported-by:`, `Cc: stable`, `Link:`, `Tested-by:`, or
`Reviewed-by:` tags
**Step 1.3 — Body analysis**
Record:
- **Bug:** `sid_to_id()` treats the last subauthority of *any*
owner/group SID as a Unix uid/gid.
- **Examples:** Everyone (`S-1-1-0`) → uid 0; `BUILTIN\Users`
(`S-1-5-32-545`) → gid 545.
- **Symptom:** SMB2 CREATE with such security descriptors causes bogus
ownership change; `notify_change()` returns `-EPERM`; CREATE fails
with `NT_STATUS_SHARING_VIOLATION`.
- **Root cause:** No validation that the SID belongs to the server
domain (owner) or `S-1-22-2` Unix group namespace (group) before RID
extraction.
- **Fix approach:** Validate SID prefix; only map domain owner SIDs and
`S-1-22-2-*` group SIDs; treat other valid Windows SIDs as unmapped so
NT ACL xattrs are preserved.
**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Although titled “validate,” this is a functional
correctness bug — incorrect ID mapping breaks SMB2 CREATE with security
descriptors and can attempt root ownership for `Everyone`.
---
## PHASE 2: DIFF ANALYSIS
**Step 2.1 — Inventory**
Record:
- **File:** `fs/smb/server/smbacl.c` (+17 / -4 lines)
- **Functions:** `sid_to_id()`, `parse_sec_desc()`
- **Scope:** Single-file surgical fix
**Step 2.2 — Code flow changes**
| Hunk | Before | After |
|------|--------|-------|
| `sid_to_id()` owner path | Extract last subauthority as uid
unconditionally | Require `psid` to match `server_conf.domain_sid`
prefix + exactly one RID |
| `sid_to_id()` group path | Extract last subauthority as gid
unconditionally | Require `psid` to match `sid_unix_groups` (`S-1-22-2`)
prefix + one RID |
| `parse_sec_desc()` error handling | `pr_err()` on mapping failure |
`ksmbd_debug()` + `rc = 0` for unmapped (non-fatal) SIDs |
**Step 2.3 — Bug mechanism**
Record: **Logic/correctness fix.** `sid_to_id()` is the inverse of
`id_to_sid()` but lacked the corresponding namespace checks. Well-known
Windows SIDs were misinterpreted as Unix IDs.
**Step 2.4 — Fix quality**
Record:
- **Obviously correct:** Mirrors `id_to_sid()` which uses
`server_conf.domain_sid` for `SIDOWNER` and `sid_unix_groups` for
groups.
- **Minimal:** Uses existing `compare_sids()`.
- **Low regression risk:** Only rejects SIDs that were never valid Unix
ID mappings.
- **Note:** `parse_sec_desc()` already ends with `return 0`; the `rc =
0` reset is defensive/cosmetic but the `sid_to_id()` validation is the
substantive fix.
---
## PHASE 3: GIT HISTORY INVESTIGATION
**Step 3.1 — Blame**
Record: Buggy `sid_to_id()` logic present at HEAD in lines 278–300,
introduced with ksmbd in this tree (blame points to merge
`5d324e5159d9e`).
**Step 3.2 — Fixes: tag**
Record: N/A — no `Fixes:` tag.
**Step 3.3 — Related file history**
Record: Recent 6.18.y ksmbd ACL hardening commits in same file:
- `337022d9dfac4` — validate ACE size against SID sub-authorities
- `18d8db24b0a5b` — validate SID in parent security descriptor during
ACL inheritance
- Multiple DACL/OOB validation fixes
This fix fits the same ACL correctness pattern already being backported.
**Step 3.4 — Author context**
Record: Namjae Jeon is the ksmbd maintainer; Steve French committed.
Both are authoritative for this subsystem.
**Step 3.5 — Dependencies**
Record: **Standalone.** Requires only symbols present in 6.18.44:
- `compare_sids()` — exists
- `server_conf.domain_sid` — exists
- `sid_unix_groups` — exists (`S-1-22-2` constant at line 43)
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
**Step 4.1 — Original discussion**
Record: `b4 dig -c fbe0bb2b75eb3` found **no matching lore thread**
(patch-id `dfb14c6056968734ff03c9e2be7c62bc06662d79`). Manual lore
search blocked by bot protection.
**Step 4.2 — Reviewers**
Record: `b4 dig -w` returned nothing (no thread found).
**Step 4.3 — Bug reports**
Record: N/A — no `Reported-by:` or `Link:` tags. Bug described only in
commit message.
**Step 4.4 — Related patches**
Record: Standalone; not part of a numbered series.
**Step 4.5 — Stable list**
Record: No stable-list discussion found (b4/lore unavailable for this
commit).
---
## PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1 — Key functions**
Record: `sid_to_id()`, `parse_sec_desc()`, `set_info_sec()`,
`smb2_create_sd_buffer()`
**Step 5.2 — Callers**
| Function | Callers | Context |
|----------|---------|---------|
| `sid_to_id()` | `parse_sec_desc()` (owner/group), DACL ACE parsing
(~line 509) | Security descriptor processing |
| `parse_sec_desc()` | `set_info_sec()` | SMB2 SET_INFO / CREATE SD
buffer |
| `set_info_sec()` | `smb2_create_sd_buffer()`, `smb2_set_info_sec()` |
SMB2 CREATE/SET_INFO from network clients |
| `smb2_create_sd_buffer()` | `smb2_open()` CREATE path (~line 3389) |
File creation with `SMB2_CREATE_SD_BUFFER` |
**Step 5.3 — Callees**
Record: `compare_sids()`, `from_vfsuid()`/`from_vfsgid()`,
`notify_change()` (downstream in `set_info_sec()`)
**Step 5.4 — Reachability**
Record: **Reachable from SMB clients** via SMB2 CREATE with security-
descriptor create context. Triggered when Windows clients send SDs
containing well-known SIDs (`Everyone`, `BUILTIN\Users`, etc.) — common
in Windows ACLs.
**Step 5.5 — Similar patterns**
Record: `id_to_sid()` already restricts mapping to
`server_conf.domain_sid` / `sid_unix_groups`; `sid_to_id()` was the
missing inverse validation.
---
## PHASE 6: CROSS-REFERENCE AGAINST LOCAL TREE (6.18.44)
**Step 6.1 — Buggy code present?**
Record: **YES.** Current `sid_to_id()` at lines 257–303 extracts RID
without prefix check. Fix commit `fbe0bb2b75eb3` is **not** an ancestor
of HEAD.
**Step 6.2 — Backport difficulty**
Record: **Clean apply** — `git apply --check` on `fbe0bb2b75eb3` patch
succeeded with no conflicts.
**Step 6.3 — Duplicate fix?**
Record: **No** — grep shows no SID prefix validation in current
`sid_to_id()`.
---
## PHASE 7: SUBSYSTEM CONTEXT
**Step 7.1 — Subsystem**
Record: `fs/smb/server/` (ksmbd SMB server). **Criticality: IMPORTANT**
— network file server, config-dependent (`CONFIG_SMB_SERVER`).
**Step 7.2 — Activity**
Record: Actively maintained in 6.18.y with recent security and ACL fixes
(UAF, OOB, ACL validation).
---
## PHASE 8: IMPACT AND RISK
**Step 8.1 — Who is affected**
Record: Users running ksmbd (`CONFIG_SMB_SERVER`) with ACL/security-
descriptor features, especially Windows SMB clients creating files with
SD buffers.
**Step 8.2 — Trigger conditions**
Record: SMB2 CREATE (or SET_INFO) carrying a security descriptor whose
owner/group SID is a well-known Windows SID (e.g. `S-1-1-0`,
`S-1-5-32-545`). **Common** in Windows environments. Triggerable by
remote SMB clients (authenticated).
**Step 8.3 — Failure mode**
Record:
- **Primary:** CREATE fails with `NT_STATUS_SHARING_VIOLATION` after
`-EPERM` from `notify_change()` — **functional breakage**
- **Secondary:** Incorrect mapping of `Everyone` → uid 0; if chown were
permitted, file would get root ownership — **correctness/security
concern**
- **Severity: MEDIUM-HIGH** for ksmbd deployments (not kernel panic, but
breaks interoperability)
**Step 8.4 — Risk/benefit**
Record:
- **Benefit:** Restores SMB2 CREATE with Windows security descriptors;
prevents bogus uid/gid assignment
- **Risk:** Very low — 21-line change, uses existing helpers, only
rejects invalid mappings
- **Ratio:** Favorable for ksmbd users
---
## PHASE 9: FINAL SYNTHESIS
**Evidence FOR backport:**
- Real, reproducible functional bug on common Windows SID patterns
- Small, surgical, applies cleanly to 6.18.44
- Obviously correct — mirrors `id_to_sid()` inverse logic
- Signed by ksmbd and SMB maintainers
- Same subsystem already receives similar ACL fixes in 6.18.y
- Remote SMB clients can trigger the bug path
**Evidence AGAINST:**
- No syzbot report or user `Reported-by:` tags
- Not a kernel crash/UAF/OOB — operational failure
- Only affects `CONFIG_SMB_SERVER` users
- No mailing-list review traceable via b4
**Stable rules checklist:**
1. Obviously correct and tested? **PASS** (logic mirrors existing
`id_to_sid()`; maintainer SOBs)
2. Fixes real bug? **PASS**
3. Important issue? **PASS** (SMB interoperability breakage; potential
incorrect root ownership)
4. Small and contained? **PASS** (21 lines, 1 file)
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** (verified clean apply)
**Exception category:** N/A (not device ID, quirk, DT, build, or docs)
**Problem summary for stable users:** Windows SMB clients sending
security descriptors with well-known SIDs (e.g. `Everyone`,
`BUILTIN\Users`) cause ksmbd to mis-map them to Unix uid/gid, attempt
invalid ownership changes, and fail file creation. The fix restricts ID
mapping to the same SID namespaces `id_to_sid()` already uses.
---
## Verification
- [Phase 1] `git show fbe0bb2b75eb3 --format=fuller`: parsed subject,
body, SOB tags
- [Phase 2] `git show fbe0bb2b75eb3`: full diff reviewed; 17 insertions,
4 deletions
- [Phase 2] Read `fs/smb/server/smbacl.c` lines 257–303, 871–958,
1601–1654: confirmed buggy code and call chain
- [Phase 3] `git describe HEAD`: v6.18.44-1-g2736c32da98b9; Makefile
VERSION=6 PATCHLEVEL=18 SUBLEVEL=44
- [Phase 3] `git merge-base --is-ancestor fbe0bb2b75eb3 HEAD`: commit
NOT in HEAD history
- [Phase 3] `git blame -L 278,300 fs/smb/server/smbacl.c`: buggy lines
present at HEAD
- [Phase 3] `git log --oneline -15 -- fs/smb/server/`: related ACL fixes
in tree
- [Phase 4] `b4 dig -c fbe0bb2b75eb3 -C`: no lore match found
- [Phase 4] WebFetch lore.kernel.org: blocked by bot protection
- [Phase 5] `grep` for `parse_sec_desc`, `set_info_sec`,
`smb2_create_sd_buffer`: traced SMB2 CREATE path
- [Phase 5] Read `compare_sids()` lines 71–114: prefix comparison
behavior verified
- [Phase 5] Read `id_to_sid()` lines 221–231: inverse mapping namespaces
confirmed
- [Phase 6] Read current `sid_to_id()`: no prefix validation present
- [Phase 6] `git apply --check` on patch: applies cleanly
- [Phase 6] `grep domain_sid`, `sid_unix_groups`: all dependencies exist
- [Phase 8] Read `smb2pdu.c` lines 2647–2672, 3388–3389: CREATE SD
buffer path confirmed
**YES**The background check finished: commit `fbe0bb2b75eb3` (“ksmbd:
validate SID namespace before mapping IDs”) is on the **7.2-rc2** line,
not in your current **6.18.44** tree — which matches the earlier finding
that the buggy `sid_to_id()` logic is still present locally and the
patch applies cleanly.
**Backport recommendation remains YES** for 6.18.y: it’s a small, self-
contained fix for a real ksmbd interoperability bug where common Windows
SIDs (e.g. `Everyone`, `BUILTIN\Users`) get mis-mapped to Unix IDs and
SMB2 CREATE with security descriptors fails.
fs/smb/server/smbacl.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index d3d0a22620f96..0b55c77e64562 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -258,6 +258,7 @@ static int sid_to_id(struct mnt_idmap *idmap,
struct smb_sid *psid, uint sidtype,
struct smb_fattr *fattr)
{
+ const struct smb_sid *sid_prefix;
int rc = -EINVAL;
/*
@@ -279,6 +280,12 @@ static int sid_to_id(struct mnt_idmap *idmap,
kuid_t uid;
uid_t id;
+ /* Only the server domain RID has a local uid representation. */
+ sid_prefix = &server_conf.domain_sid;
+ if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
+ compare_sids(psid, sid_prefix))
+ return -EINVAL;
+
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
uid = KUIDT_INIT(id);
uid = from_vfsuid(idmap, &init_user_ns, VFSUIDT_INIT(uid));
@@ -290,6 +297,12 @@ static int sid_to_id(struct mnt_idmap *idmap,
kgid_t gid;
gid_t id;
+ /* Local gids are represented by S-1-22-2-<gid>. */
+ sid_prefix = &sid_unix_groups;
+ if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
+ compare_sids(psid, sid_prefix))
+ return -EINVAL;
+
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
gid = KGIDT_INIT(id);
gid = from_vfsgid(idmap, &init_user_ns, VFSGIDT_INIT(gid));
@@ -916,9 +929,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
rc = sid_to_id(idmap, owner_sid_ptr, SIDOWNER, fattr);
if (rc) {
- pr_err("%s: Error %d mapping Owner SID to uid\n",
- __func__, rc);
+ ksmbd_debug(SMB, "Owner SID has no Unix uid mapping\n");
owner_sid_ptr = NULL;
+ rc = 0;
}
}
@@ -934,9 +947,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
}
rc = sid_to_id(idmap, group_sid_ptr, SIDUNIX_GROUP, fattr);
if (rc) {
- pr_err("%s: Error %d mapping Group SID to gid\n",
- __func__, rc);
+ ksmbd_debug(SMB, "Group SID has no Unix gid mapping\n");
group_sid_ptr = NULL;
+ rc = 0;
}
}
--
2.53.0
next prev parent reply other threads:[~2026-08-31 13:45 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:20 ` [PATCH AUTOSEL 6.18-6.6] ksmbd: preserve VFS inherited POSIX ACL mask Sasha Levin
2026-08-31 13:20 ` [PATCH AUTOSEL 6.18-6.1] ksmbd: fix outstanding credit leak on abort and error paths Sasha Levin
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-6.12] cifs: Fix support for creating SFU fifo Sasha Levin
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: find bound sessions during reauthentication Sasha Levin
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18] ksmbd: propagate failed command status in related compounds Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-6.6] ksmbd: treat read-control opens as stat opens only for leases Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: mark invalid session responses as signed Sasha Levin
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: Fix acl.sd_buf memory leak and invalid sd_size error handling Sasha Levin
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18-6.1] ksmbd: start file id allocation at 1 Sasha Levin
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18-6.1] smb/client: reduce fallocate zero buffer allocation Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] cifs: Fix support for creating SFU socket Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: apply create security descriptor first Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.1] smb: client: bound dirent name against end of SMB response in cifs_filldir Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-5.10] cifs: validate idmap key payload length Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-6.6] ksmbd: validate SMB2 lease create contexts Sasha Levin
2026-08-31 13:26 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: fix credit charge calculation for SMB2 QUERY_INFO Sasha Levin
2026-08-31 13:27 ` Sasha Levin [this message]
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-6.12] smb/client: zero-initialize stack-allocated cifs_open_info_data Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: break RH leases before delete-on-close Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18] smb/client: emulate small EOF-extending mode 0 fallocate ranges Sasha Levin
2026-08-31 13:28 ` [PATCH AUTOSEL 6.18] smb/client: do not account EOF extension as allocation Sasha Levin
2026-08-31 13:28 ` [PATCH AUTOSEL 6.18-6.6] smb/client: flush dirty data before punching a hole Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-6.6] smb: client: fix races in cifsd thread creation Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-6.6] ksmbd: fix lease break and ack state handling Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: fix n.data memory leak in ksmbd_vfs_set_dos_attrib_xattr Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.1] ksmbd: align SMB2 oplock break ack handling Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-6.6] ksmbd: deny renaming directory with open children Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.15] ksmbd: treat unnamed DATA stream as base file Sasha Levin
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=20260831133314.4125787-405-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=smfrench@gmail.com \
--cc=stable@vger.kernel.org \
--cc=stfrench@microsoft.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