mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-07 22:42:04 +00:00
kernel: Add noaudit variant of ns_capable()
When checking the current cred for a capability in a specific user namespace, it isn't always desirable to have the LSMs audit the check. This patch adds a noaudit variant of ns_capable() for when those situations arise. The common logic between ns_capable() and the new ns_capable_noaudit() is moved into a single, shared function to keep duplicated code to a minimum and ease maintainability. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> Signed-off-by: James Morris <james.l.morris@oracle.com>
This commit is contained in:
parent
2885c1e3e0
commit
98f368e9e2
@ -206,6 +206,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
|
|||||||
struct user_namespace *ns, int cap);
|
struct user_namespace *ns, int cap);
|
||||||
extern bool capable(int cap);
|
extern bool capable(int cap);
|
||||||
extern bool ns_capable(struct user_namespace *ns, int cap);
|
extern bool ns_capable(struct user_namespace *ns, int cap);
|
||||||
|
extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
|
||||||
#else
|
#else
|
||||||
static inline bool has_capability(struct task_struct *t, int cap)
|
static inline bool has_capability(struct task_struct *t, int cap)
|
||||||
{
|
{
|
||||||
@ -233,6 +234,10 @@ static inline bool ns_capable(struct user_namespace *ns, int cap)
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif /* CONFIG_MULTIUSER */
|
#endif /* CONFIG_MULTIUSER */
|
||||||
extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
|
extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
|
||||||
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
|
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
|
||||||
|
@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
|
|||||||
return has_ns_capability_noaudit(t, &init_user_ns, cap);
|
return has_ns_capability_noaudit(t, &init_user_ns, cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
|
||||||
|
{
|
||||||
|
int capable;
|
||||||
|
|
||||||
|
if (unlikely(!cap_valid(cap))) {
|
||||||
|
pr_crit("capable() called with invalid cap=%u\n", cap);
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
capable = audit ? security_capable(current_cred(), ns, cap) :
|
||||||
|
security_capable_noaudit(current_cred(), ns, cap);
|
||||||
|
if (capable == 0) {
|
||||||
|
current->flags |= PF_SUPERPRIV;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ns_capable - Determine if the current task has a superior capability in effect
|
* ns_capable - Determine if the current task has a superior capability in effect
|
||||||
* @ns: The usernamespace we want the capability in
|
* @ns: The usernamespace we want the capability in
|
||||||
@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
|
|||||||
*/
|
*/
|
||||||
bool ns_capable(struct user_namespace *ns, int cap)
|
bool ns_capable(struct user_namespace *ns, int cap)
|
||||||
{
|
{
|
||||||
if (unlikely(!cap_valid(cap))) {
|
return ns_capable_common(ns, cap, true);
|
||||||
pr_crit("capable() called with invalid cap=%u\n", cap);
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (security_capable(current_cred(), ns, cap) == 0) {
|
|
||||||
current->flags |= PF_SUPERPRIV;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ns_capable);
|
EXPORT_SYMBOL(ns_capable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ns_capable_noaudit - Determine if the current task has a superior capability
|
||||||
|
* (unaudited) in effect
|
||||||
|
* @ns: The usernamespace we want the capability in
|
||||||
|
* @cap: The capability to be tested for
|
||||||
|
*
|
||||||
|
* Return true if the current task has the given superior capability currently
|
||||||
|
* available for use, false if not.
|
||||||
|
*
|
||||||
|
* This sets PF_SUPERPRIV on the task if the capability is available on the
|
||||||
|
* assumption that it's about to be used.
|
||||||
|
*/
|
||||||
|
bool ns_capable_noaudit(struct user_namespace *ns, int cap)
|
||||||
|
{
|
||||||
|
return ns_capable_common(ns, cap, false);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ns_capable_noaudit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* capable - Determine if the current task has a superior capability in effect
|
* capable - Determine if the current task has a superior capability in effect
|
||||||
|
Loading…
Reference in New Issue
Block a user