ntfs3: no permission check on system.ntfs_security and system.ntfs_attrib xattrs
Vivek Parikh <[email protected]>
| Newsgroups | dev.linux.lists.ntfs3 |
|---|---|
| Message-ID | <CABYdpihXucDUdmj402-rOjRUuCXPaxe8a=XoBoJ8wbvAnsAu9g@mail.gmail.com> |
Hi,
In fs/ntfs3, the system.ntfs_security, system.ntfs_attrib,
system.ntfs_attrib_be and system.dos_attrib xattrs have no permission
check. Any local user who can path-walk to a file can read and replace
its Windows security descriptor and NTFS attributes, including on a file
owned by root with mode 000.
The VFS deliberately leaves system.* to the filesystem (fs/xattr.c:
"No restriction for security.* and system.* from the VFS. Decision on
these is left to the underlying filesystem"), and may_write_xattr()
checks only immutable/append/unmapped-id. ntfs3 then checks nothing for
these four names. It does gate the WSL names:
fs/ntfs3/xattr.c:967
if (ntfs_is_reserved_lxattr(name) && !capable(CAP_SYS_ADMIN))
That is the only capability check in the file, so $LXUID is protected
and the Windows security descriptor is not.
Affected
fs/ntfs3, present since ntfs3 was merged in 5.15.
Verified on v7.2-rc7 (11028ab62899) and on Ubuntu 24.04
6.17.0-1019-aws with the in-tree ntfs3.ko.
Reproduction
On an ntfs3 mount whose directories are traversable by other users
(mode 755), with a target file owned by root, mode 000:
getxattr(path, "system.ntfs_security", ...) succeeds
setxattr(path, "system.ntfs_security", sd, ...) succeeds
setxattr(path, "system.$LXUID", ...) EACCES
open(path, O_RDONLY) EACCES
Measured as uid 1002: GET returned 80 bytes, SET of a descriptor
granting Everyone full control returned 0, the read-back matched, and
the value survived umount/mount. The $LXUID line above is the same
user and the same file in the same run, which is what shows the
inconsistency rather than a general lack of checks.
A reproducer exists and is not attached, per the security-bugs.rst
guidance for reports that go to a public list. Happy to send it on
request.
Impact
An unprivileged user cannot read the file's contents through Linux DAC
-- open() still fails -- but can rewrite the file's stored access
control metadata. Where the volume is later mounted by Windows, the
descriptor is honoured there; on our test volume the resulting
descriptor was O:WD G:WD D:P(A;;FA;;;WD), that is, owner Everyone and
full access to Everyone.
Not claimed: this is not a Linux privilege escalation, is not remotely
reachable, and does not bypass Linux file permissions.
Exposure depends on the mount. A per-user udisks mount is not
affected because other users cannot traverse it. The case that matters
is a shared or dual-boot mount that is traversable by several local
users.
Fix direction
Apply the permission the VFS would apply for user.* before handling
these four names: inode_permission(idmap, inode, MAY_READ) on get and
MAY_WRITE on set, in ntfs_getxattr()/ntfs_setxattr(). Optionally
inode_owner_or_capable() for the descriptor write, matching chmod.
We have a sketch of this but have not tested it, so we are not sending
it as a patch.
This was found with AI assistance and we are treating it as public
accordingly. It was verified against the source and reproduced before
sending. If it is already known or you do not consider it a security
issue, please say so and we will record that.
Regards,
Vivek Parikh
Lead Researcher - Zero-Day Research Labs
BreachX
[email protected]
Alternate email: [email protected]