27
27
#include <linux/mnt_idmapping.h>
28
28
#include <uapi/linux/lsm.h>
29
29
30
+ #define CREATE_TRACE_POINTS
31
+ #include <trace/events/capability.h>
32
+
30
33
/*
31
34
* If a non-root user executes a setuid-root binary in
32
35
* !secure(SECURE_NOROOT) mode, then we raise capabilities.
@@ -50,46 +53,46 @@ static void warn_setuid_and_fcaps_mixed(const char *fname)
50
53
}
51
54
52
55
/**
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.
54
58
* @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
56
61
* @cap: The capability to check for
57
- * @opts: Bitmask of options defined in include/linux/security.h
58
62
*
59
63
* Determine whether the nominated task has the specified capability amongst
60
64
* its effective set, returning 0 if it does, -ve if it does not.
61
65
*
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.
66
67
*/
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 )
69
72
{
70
- struct user_namespace * ns = targ_ns ;
73
+ struct user_namespace * ns = target_ns ;
71
74
72
75
/* See if cred has the capability in the target user namespace
73
76
* by examining the target user namespace and all of the target
74
77
* user namespace's parents.
75
78
*/
76
79
for (;;) {
77
80
/* Do we have the necessary capabilities? */
78
- if (ns == cred -> user_ns )
81
+ if (likely ( ns == cred_ns ) )
79
82
return cap_raised (cred -> cap_effective , cap ) ? 0 : - EPERM ;
80
83
81
84
/*
82
85
* If we're already at a lower level than we're looking for,
83
86
* we're done searching.
84
87
*/
85
- if (ns -> level <= cred -> user_ns -> level )
88
+ if (ns -> level <= cred_ns -> level )
86
89
return - EPERM ;
87
90
88
91
/*
89
92
* The owner of the user namespace in the parent of the
90
93
* user namespace has all caps.
91
94
*/
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 ))
93
96
return 0 ;
94
97
95
98
/*
@@ -102,6 +105,31 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
102
105
/* We never get here */
103
106
}
104
107
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
+
105
133
/**
106
134
* cap_settime - Determine whether the current process may set the system clock
107
135
* @ts: The time to set
@@ -1445,12 +1473,6 @@ int cap_mmap_addr(unsigned long addr)
1445
1473
return ret ;
1446
1474
}
1447
1475
1448
- int cap_mmap_file (struct file * file , unsigned long reqprot ,
1449
- unsigned long prot , unsigned long flags )
1450
- {
1451
- return 0 ;
1452
- }
1453
-
1454
1476
#ifdef CONFIG_SECURITY
1455
1477
1456
1478
static const struct lsm_id capability_lsmid = {
@@ -1470,7 +1492,6 @@ static struct security_hook_list capability_hooks[] __ro_after_init = {
1470
1492
LSM_HOOK_INIT (inode_killpriv , cap_inode_killpriv ),
1471
1493
LSM_HOOK_INIT (inode_getsecurity , cap_inode_getsecurity ),
1472
1494
LSM_HOOK_INIT (mmap_addr , cap_mmap_addr ),
1473
- LSM_HOOK_INIT (mmap_file , cap_mmap_file ),
1474
1495
LSM_HOOK_INIT (task_fix_setuid , cap_task_fix_setuid ),
1475
1496
LSM_HOOK_INIT (task_prctl , cap_task_prctl ),
1476
1497
LSM_HOOK_INIT (task_setscheduler , cap_task_setscheduler ),
0 commit comments