2727#include <linux/mnt_idmapping.h>
2828#include <uapi/linux/lsm.h>
2929
30+ #define CREATE_TRACE_POINTS
31+ #include <trace/events/capability.h>
32+
3033/*
3134 * If a non-root user executes a setuid-root binary in
3235 * !secure(SECURE_NOROOT) mode, then we raise capabilities.
@@ -50,46 +53,46 @@ static void warn_setuid_and_fcaps_mixed(const char *fname)
5053}
5154
5255/**
53- * cap_capable - Determine whether a task has a particular effective capability
56+ * cap_capable_helper - Determine whether a task has a particular effective
57+ * capability.
5458 * @cred: The credentials to use
55- * @targ_ns: The user namespace in which we need the capability
59+ * @target_ns: The user namespace of the resource being accessed
60+ * @cred_ns: The user namespace of the credentials
5661 * @cap: The capability to check for
57- * @opts: Bitmask of options defined in include/linux/security.h
5862 *
5963 * Determine whether the nominated task has the specified capability amongst
6064 * its effective set, returning 0 if it does, -ve if it does not.
6165 *
62- * NOTE WELL: cap_has_capability() cannot be used like the kernel's capable()
63- * and has_capability() functions. That is, it has the reverse semantics:
64- * cap_has_capability() returns 0 when a task has a capability, but the
65- * kernel's capable() and has_capability() returns 1 for this case.
66+ * See cap_capable for more details.
6667 */
67- int cap_capable (const struct cred * cred , struct user_namespace * targ_ns ,
68- int cap , unsigned int opts )
68+ static inline int cap_capable_helper (const struct cred * cred ,
69+ struct user_namespace * target_ns ,
70+ const struct user_namespace * cred_ns ,
71+ int cap )
6972{
70- struct user_namespace * ns = targ_ns ;
73+ struct user_namespace * ns = target_ns ;
7174
7275 /* See if cred has the capability in the target user namespace
7376 * by examining the target user namespace and all of the target
7477 * user namespace's parents.
7578 */
7679 for (;;) {
7780 /* Do we have the necessary capabilities? */
78- if (ns == cred -> user_ns )
81+ if (likely ( ns == cred_ns ) )
7982 return cap_raised (cred -> cap_effective , cap ) ? 0 : - EPERM ;
8083
8184 /*
8285 * If we're already at a lower level than we're looking for,
8386 * we're done searching.
8487 */
85- if (ns -> level <= cred -> user_ns -> level )
88+ if (ns -> level <= cred_ns -> level )
8689 return - EPERM ;
8790
8891 /*
8992 * The owner of the user namespace in the parent of the
9093 * user namespace has all caps.
9194 */
92- if ((ns -> parent == cred -> user_ns ) && uid_eq (ns -> owner , cred -> euid ))
95+ if ((ns -> parent == cred_ns ) && uid_eq (ns -> owner , cred -> euid ))
9396 return 0 ;
9497
9598 /*
@@ -102,6 +105,31 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
102105 /* We never get here */
103106}
104107
108+ /**
109+ * cap_capable - Determine whether a task has a particular effective capability
110+ * @cred: The credentials to use
111+ * @target_ns: The user namespace of the resource being accessed
112+ * @cap: The capability to check for
113+ * @opts: Bitmask of options defined in include/linux/security.h (unused)
114+ *
115+ * Determine whether the nominated task has the specified capability amongst
116+ * its effective set, returning 0 if it does, -ve if it does not.
117+ *
118+ * NOTE WELL: cap_has_capability() cannot be used like the kernel's capable()
119+ * and has_capability() functions. That is, it has the reverse semantics:
120+ * cap_has_capability() returns 0 when a task has a capability, but the
121+ * kernel's capable() and has_capability() returns 1 for this case.
122+ */
123+ int cap_capable (const struct cred * cred , struct user_namespace * target_ns ,
124+ int cap , unsigned int opts )
125+ {
126+ const struct user_namespace * cred_ns = cred -> user_ns ;
127+ int ret = cap_capable_helper (cred , target_ns , cred_ns , cap );
128+
129+ trace_cap_capable (cred , target_ns , cred_ns , cap , ret );
130+ return ret ;
131+ }
132+
105133/**
106134 * cap_settime - Determine whether the current process may set the system clock
107135 * @ts: The time to set
@@ -1445,12 +1473,6 @@ int cap_mmap_addr(unsigned long addr)
14451473 return ret ;
14461474}
14471475
1448- int cap_mmap_file (struct file * file , unsigned long reqprot ,
1449- unsigned long prot , unsigned long flags )
1450- {
1451- return 0 ;
1452- }
1453-
14541476#ifdef CONFIG_SECURITY
14551477
14561478static const struct lsm_id capability_lsmid = {
@@ -1470,7 +1492,6 @@ static struct security_hook_list capability_hooks[] __ro_after_init = {
14701492 LSM_HOOK_INIT (inode_killpriv , cap_inode_killpriv ),
14711493 LSM_HOOK_INIT (inode_getsecurity , cap_inode_getsecurity ),
14721494 LSM_HOOK_INIT (mmap_addr , cap_mmap_addr ),
1473- LSM_HOOK_INIT (mmap_file , cap_mmap_file ),
14741495 LSM_HOOK_INIT (task_fix_setuid , cap_task_fix_setuid ),
14751496 LSM_HOOK_INIT (task_prctl , cap_task_prctl ),
14761497 LSM_HOOK_INIT (task_setscheduler , cap_task_setscheduler ),
0 commit comments