[SRU][J][PATCH 1/2] UBUNTU: SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Skip permission checking for trusted.overlayfs.* xattrs"
Massimiliano Pellizzer
massimiliano.pellizzer at canonical.com
Tue Mar 31 18:26:01 UTC 2026
This reverts commit 3fb38c98e060b327cb58373775dcc95ed52d1f22.
The reverted commit bypasses vfs_setxattr() in ovl_do_setxattr() by
calling __vfs_setxattr_noperm() directly. After After upstream commit
c914c0e27eb0 ("ovl: use wrappers to all vfs_*xattr() calls")
was backported, this routed security.capability writes during copy-up
through the unchecked path, bypassing cap_convert_nscap() and enabling
CVE-2023-2640 and CVE-2023-32629.
CVE-2023-2640
CVE-2023-32629
Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer at canonical.com>
---
fs/overlayfs/overlayfs.h | 15 ++-------------
fs/xattr.c | 36 ++++++------------------------------
include/linux/xattr.h | 1 -
3 files changed, 8 insertions(+), 44 deletions(-)
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 585797e23b547..43b211cf437cc 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -211,12 +211,7 @@ static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
const char *name, const void *value,
size_t size, int flags)
{
- struct inode *inode = dentry->d_inode;
- int err;
-
- inode_lock(inode);
- err = __vfs_setxattr_noperm(&init_user_ns, dentry, name, value, size, flags);
- inode_unlock(inode);
+ int err = vfs_setxattr(&init_user_ns, dentry, name, value, size, flags);
pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n",
dentry, name, min((int)size, 48), value, size, flags, err);
@@ -233,13 +228,7 @@ static inline int ovl_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry,
const char *name)
{
- struct inode *inode = dentry->d_inode;
- int err;
-
- inode_lock(inode);
- err = __vfs_removexattr_noperm(&init_user_ns, dentry, name);
- inode_unlock(inode);
-
+ int err = vfs_removexattr(&init_user_ns, dentry, name);
pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err);
return err;
}
diff --git a/fs/xattr.c b/fs/xattr.c
index bad89a9144cc7..030f93f3f9d0e 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -239,7 +239,6 @@ int __vfs_setxattr_noperm(struct user_namespace *mnt_userns,
return error;
}
-EXPORT_SYMBOL_GPL(__vfs_setxattr_noperm);
/**
* __vfs_setxattr_locked - set an extended attribute while holding the inode
@@ -474,34 +473,6 @@ __vfs_removexattr(struct user_namespace *mnt_userns, struct dentry *dentry,
}
EXPORT_SYMBOL(__vfs_removexattr);
-/**
- * __vfs_removexattr_noperm - perform removexattr operation without
- * performing permission checks.
- *
- * @dentry - object to perform setxattr on
- * @name - xattr name to set
- *
- * returns the result of the internal setxattr or setsecurity operations.
- *
- * This function requires the caller to lock the inode's i_mutex before it
- * is executed. It also assumes that the caller will make the appropriate
- * permission checks.
- */
-int
-__vfs_removexattr_noperm(struct user_namespace *mnt_userns,
- struct dentry *dentry, const char *name)
-{
- int error;
-
- error =__vfs_removexattr(mnt_userns, dentry, name);
- if (!error) {
- fsnotify_xattr(dentry);
- evm_inode_post_removexattr(dentry, name);
- }
- return error;
-}
-EXPORT_SYMBOL_GPL(__vfs_removexattr_noperm);
-
/**
* __vfs_removexattr_locked - set an extended attribute while holding the inode
* lock
@@ -532,7 +503,12 @@ __vfs_removexattr_locked(struct user_namespace *mnt_userns,
if (error)
goto out;
- error = __vfs_removexattr_noperm(mnt_userns, dentry, name);
+ error = __vfs_removexattr(mnt_userns, dentry, name);
+
+ if (!error) {
+ fsnotify_xattr(dentry);
+ evm_inode_post_removexattr(dentry, name);
+ }
out:
return error;
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 077b3844f2eeb..4c379d23ec6e7 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -63,7 +63,6 @@ int __vfs_setxattr_locked(struct user_namespace *, struct dentry *,
int vfs_setxattr(struct user_namespace *, struct dentry *, const char *,
const void *, size_t, int);
int __vfs_removexattr(struct user_namespace *, struct dentry *, const char *);
-int __vfs_removexattr_noperm(struct user_namespace *, struct dentry *, const char *);
int __vfs_removexattr_locked(struct user_namespace *, struct dentry *,
const char *, struct inode **);
int vfs_removexattr(struct user_namespace *, struct dentry *, const char *);
--
2.51.0
More information about the kernel-team
mailing list