]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ntfs3: reject direct userspace writes to reserved $LX* xattrs
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Wed, 10 Jun 2026 10:31:01 +0000 (12:31 +0200)
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Wed, 10 Jun 2026 10:37:10 +0000 (12:37 +0200)
NTFS3 uses $LXUID, $LXGID, $LXMOD and $LXDEV as internal WSL
permission metadata and reloads them into i_uid, i_gid and i_mode
from ntfs_get_wsl_perm().

Because the empty-prefix xattr handler also lets file owners call
setxattr() on these names directly, an unprivileged writer on a
writable ntfs3 mount can plant root ownership and S_ISUID on their own
file and gain euid 0 after inode reload.

Reject direct userspace writes to the reserved $LX* names. Internal
ntfs3 metadata updates are unchanged because ntfs_save_wsl_perm()
writes them via ntfs_set_ea() directly.

Signed-off-by: Zhen Yan <sdjasjbuaa@gmail.com>
[almaz.alexandrovich@paragon-software.com: added an additional check for non privileged users]
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
fs/ntfs3/xattr.c

index 7e5118247660d07c8e6fe57fce803f2b4deb288f..04814dd2937529b5aebbd7a013429210dc16a2b8 100644 (file)
@@ -851,6 +851,12 @@ out:
        return err;
 }
 
+static bool ntfs_is_reserved_lxattr(const char *name)
+{
+       return !strcmp(name, "$LXUID") || !strcmp(name, "$LXGID") ||
+              !strcmp(name, "$LXMOD") || !strcmp(name, "$LXDEV");
+}
+
 /*
  * ntfs_setxattr - inode_operations::setxattr
  */
@@ -957,6 +963,12 @@ set_new_fa:
                goto out;
        }
 
+       /* Do not allow non privileged users to change $LXUID/$LXGID... */
+       if (ntfs_is_reserved_lxattr(name) && !capable(CAP_SYS_ADMIN)) {
+               err = -EPERM;
+               goto out;
+       }
+
        /* Deal with NTFS extended attribute. */
        err = ntfs_set_ea(inode, name, strlen(name), value, size, flags, 0,
                          NULL);