Proof/Linux kernel/ksmbd: preserve VFS POSIX ACL mask
The VFS computed the ACL. KSMBD overwrote it.
The VFS had already derived the child’s access and default ACLs from the parent ACL and the requested mode. KSMBD then reloaded the parent ACL, forced ACL_MASK to full rwx, and installed that instead.
POSIX ACLs express permissions for named users and groups in addition to the traditional owner, group and other mode bits. The ACL_MASK entry is the effective permission ceiling applied to named-user, named-group and owning-group entries.
user:someuser:rwx
mask::---The VFS inheritance path takes the parent’s default ACL and the requested file mode into account when constructing a new child. That result is the security answer downstream code should preserve.
KSMBD must preserve the child ACL and effective mask produced by the VFS; it must not reload the parent ACL after creation and broaden the result.
The problem is not that KSMBD handled ACLs at all. It is that this happened after the VFS had already performed inheritance and mode-based normalization — discarding the VFS-computed effective mask and replacing it with a broader one.
Before the accepted patch, ksmbd_vfs_inherit_posix_acl() obtained the parent default ACL and modified its mask entry:
acls = get_inode_acl(parent_inode, ACL_TYPE_DEFAULT);
if (IS_ERR_OR_NULL(acls))
return -ENOENT;
pace = acls->a_entries;
for (i = 0; i < acls->a_count; i++, pace++) {
if (pace->e_tag == ACL_MASK) {
pace->e_perm = 0x07;
break;
}
}0x07 is full rwx. The helper then installed that ACL on the child as its access ACL and, for directories, as its default ACL:
rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
if (S_ISDIR(inode->i_mode))
rc = set_posix_acl(idmap, dentry, ACL_TYPE_DEFAULT, acls);The bounded research scenario uses two distinct authenticated principals: a creator allowed to create a child through the SMB share, and another named principal whose ACL entry exists but is intentionally suppressed by a restrictive mask.
Restrictive parent ACL
A named entry records rwx; the mask suppresses it.
SMB path
The VFS computes the correct child ACL first.
Mask forced to rwx
KSMBD reloads the parent ACL and installs a broader result.
Directory defaults
For directories, the widened ACL can flow into later descendants.
With ordinary local/VFS creation under the equivalent parent ACL, the restrictive mask stays effective and the second principal is denied. With the vulnerable KSMBD rewrite, the child ACL can instead acquire mask::rwx, activating permissions that were recorded but ineffective.
The original research used an owned disposable Linux/KSMBD environment and compared local creation with SMB creation under the same restrictive default ACL.
VFS creation
An object created locally beneath the parent keeps the named principal restricted by the inherited mask.
KSMBD creation
The equivalent object’s access ACL shows the widened effective mask.
Access divergence
The local control remains denied while the SMB-created object becomes readable or writable.
| Boundary | Result |
|---|---|
| Administrator policy | Parent default POSIX ACL with restrictive mask |
| Trusted kernel result | VFS-computed child access/default ACL |
| KSMBD error | Post-create parent ACL reload plus forced ACL_MASK = rwx |
| Consequence | Effective permissions on new SMB-created objects can exceed intent |
This is a post-processing bug: the initial security mechanism works, and a later subsystem helper overwrites the correct result.
Compare the two creation paths, not the code alone.
An ACL helper reads plausibly in isolation. The finding only becomes concrete when the same parent directory produces one permission result locally and a different one over SMB.
Source mapping
Locate every point where KSMBD touches ACL state after the VFS has created the inode.
Ordering hypothesis
Ask whether a second inheritance pass can contradict a completed VFS decision.
Differential construction
Create equivalent objects locally and through SMB under one restrictive parent ACL.
Skeptic gate
Use a genuinely separate principal, and hold the claim to newly created objects and descendants.
Report and upstream review
Report to the KSMBD maintainers; credit patch authorship where it belongs.
Mainline commit e148e567a925 removes the mask mutation and the subsequent set_posix_acl() calls:
- pace = acls->a_entries;
-
- for (i = 0; i < acls->a_count; i++, pace++) {
- if (pace->e_tag == ACL_MASK) {
- pace->e_perm = 0x07;
- break;
- }
- }
-
- rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
- ...
+ posix_acl_release(acls);
+ return 0;The fixed helper still detects whether the parent has a default ACL, but no longer re-applies or broadens that ACL after the VFS creation path has done the correct inheritance work.
The VFS initializes a child's POSIX ACL from the parent's default ACL and
the requested creation mode. Do not mutate the parent ACL or overwrite the
child's VFS-computed access and default ACLs afterwards.
This preserves restrictive ACL_MASK entries and prevents SMB object creation
from widening effective permissions.
Reported-by: Charles Vosburgh <trilobyte777@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>The accepted commit fixes pre-existing behaviour but does not publish a complete affected-version range, and this page does not invent one.
| Tag | Fix present | Basis |
|---|---|---|
| Linux 7.1.3 | no | original validation reproduced the behaviour here |
| v7.2-rc4 | no | public tag containment check |
| v7.2-rc5 | yes | first verified mainline tag containing the fix |
| Linux 7.2 | yes | final mainline release |
The exact introducing commit was not independently established during the bounded review. The upstream commit assigns no CVE or CVSS score, so none is asserted here.
A strong KSMBD regression test should:
- configure a parent directory with a restrictive default ACL mask and a named principal;
- create equivalent children locally and through SMB;
- compare the resulting ACLs and effective permissions;
- test both files and directories;
- test a descendant beneath an SMB-created directory; and
- verify that KSMBD does not mutate the parent cached or on-disk ACL as part of child creation.
The ACL attached to a new inode after VFS creation is authoritative unless a later operation has explicit, policy-backed reason to change it.
Credit: Reported by Charles Vosburgh, credited upstream through the accepted commit’s Reported-by trailer. The accepted patch was authored by Namjae Jeon and signed into the SMB tree by Steve French. This page preserves that distinction rather than presenting reporting credit as patch authorship.