[Devel] [PATCH RHEL8 COMMIT] overlayfs: relax capable check for trusted prefix xattrs
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Jun 21 21:05:30 MSK 2021
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.47
------>
commit aee8f9c25de5bf6b62bca3b64178badfc185cb75
Author: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
Date: Mon Jun 21 21:05:30 2021 +0300
overlayfs: relax capable check for trusted prefix xattrs
ovl_listxattr() additionally check if attributes can be shown to user by
calling capable(). Change it to ve_capable() to avoid problems in containers.
https://jira.sw.ru/browse/PSBM-124532
Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
(cherry-picked from vz commit 2a2b9806906460afcddda2cd273a9933504ee8b9)
conflicts:
In the original patch capable() has been changed to ve_capable(), but in
VZ8 capable() is not used anymore and is substituted by
ns_capable_noaudit(), in 5c2e9f346b815841f9bed6029ebcb06415caf640.
I have examined this patch.
What it does is removes unneeded audit log in ovl_listxattr: during
listxattr, some trusted xattrs can be met by the listing algorithm, they
will be filtered out from the output and not shown to the user.
In the filtering function, that decides which xattrs should be hidden,
both capable() and ns_capable_noaudit() served the same function to say
yes or no to the filtering function, but capable() did that with
additionally doing an audit log (a kind of a warning in the logs), which
is not needed in reality as this was an internal kernel checking
function, not the actual userspace request to access a trusted object,
userspace will never see this item.
So ns_capability_noaudit() - has the same functionality as capable()
except for it also passes the flag to selinux_capable() to NOT perform
an audit log, still it will decide should the attribute be visible to
the user or not in the same way.
To call ns_capable_noaudit() in the same way ve_capable() calls
ns_capable(), ve_capable_noaudit() has been added in the same
cherry-pick patch.
https://jira.sw.ru/browse/PSBM-127858
Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
---
fs/overlayfs/inode.c | 2 +-
include/linux/capability.h | 1 +
kernel/capability.c | 23 +++++++++++++++++++++++
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 109096867ef9..583427c08be6 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -401,7 +401,7 @@ static bool ovl_can_list(const char *s)
/* Never list trusted.overlay, list other trusted for superuser only */
return !ovl_is_private_xattr(s) &&
- ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
+ ve_capable_noaudit(CAP_SYS_ADMIN);
}
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 2cd6cc8ead53..814d2ac1bb1e 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -210,6 +210,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
extern bool capable(int cap);
extern bool ns_capable(struct user_namespace *ns, int cap);
extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
+extern bool ve_capable_noaudit(int cap);
#else
static inline bool has_capability(struct task_struct *t, int cap)
{
diff --git a/kernel/capability.c b/kernel/capability.c
index 5f1c6cb2af07..6e646cd4187f 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -418,6 +418,23 @@ bool ve_capable(int cap)
return ret;
}
+bool ve_capable_noaudit(int cap)
+{
+ struct cred *cred;
+ bool ret;
+
+ rcu_read_lock();
+ cred = get_exec_env()->init_cred;
+
+ if (cred == NULL) /* ve isn't running */
+ cred = ve0.init_cred;
+
+ ret = ns_capable_noaudit(cred->user_ns, cap);
+ rcu_read_unlock();
+
+ return ret;
+}
+
bool feature_capable(int feature, int cap)
{
if (get_exec_env()->features & feature)
@@ -431,12 +448,18 @@ bool ve_capable(int cap)
return capable(cap);
}
+bool ve_capable_noaudit(int cap)
+{
+ return ns_capable_noaudit(&init_user_ns, cap);
+}
+
bool feature_capable(int feature, int cap)
{
return capable(cap);
}
#endif
EXPORT_SYMBOL_GPL(ve_capable);
+EXPORT_SYMBOL_GPL(ve_capable_noaudit);
/**
* ns_capable_noaudit - Determine if the current task has a superior capability
More information about the Devel
mailing list