Skip to content

Commit 754916d

Browse files
committed
Merge tag 'caps-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux
Pull capabilities updates from Serge Hallyn: - remove the cap_mmap_file() hook, as it simply returned the default return value and so doesn't need to exist (Paul Moore) - add a trace event for cap_capable() (Jordan Rome) * tag 'caps-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux: security: add trace event for cap_capable capabilities: remove cap_mmap_file()
2 parents 21266b8 + d48da4d commit 754916d

File tree

3 files changed

+99
-20
lines changed

3 files changed

+99
-20
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5182,6 +5182,7 @@ M: Serge Hallyn <[email protected]>
51825182
51835183
S: Supported
51845184
F: include/linux/capability.h
5185+
F: include/trace/events/capability.h
51855186
F: include/uapi/linux/capability.h
51865187
F: kernel/capability.c
51875188
F: security/commoncap.c

include/trace/events/capability.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#undef TRACE_SYSTEM
3+
#define TRACE_SYSTEM capability
4+
5+
#if !defined(_TRACE_CAPABILITY_H) || defined(TRACE_HEADER_MULTI_READ)
6+
#define _TRACE_CAPABILITY_H
7+
8+
#include <linux/cred.h>
9+
#include <linux/tracepoint.h>
10+
#include <linux/user_namespace.h>
11+
12+
/**
13+
* cap_capable - called after it's determined if a task has a particular
14+
* effective capability
15+
*
16+
* @cred: The credentials used
17+
* @target_ns: The user namespace of the resource being accessed
18+
* @capable_ns: The user namespace in which the credential provides the
19+
* capability to access the targeted resource.
20+
* This will be NULL if ret is not 0.
21+
* @cap: The capability to check for
22+
* @ret: The return value of the check: 0 if it does, -ve if it does not
23+
*
24+
* Allows to trace calls to cap_capable in commoncap.c
25+
*/
26+
TRACE_EVENT(cap_capable,
27+
28+
TP_PROTO(const struct cred *cred, struct user_namespace *target_ns,
29+
const struct user_namespace *capable_ns, int cap, int ret),
30+
31+
TP_ARGS(cred, target_ns, capable_ns, cap, ret),
32+
33+
TP_STRUCT__entry(
34+
__field(const struct cred *, cred)
35+
__field(struct user_namespace *, target_ns)
36+
__field(const struct user_namespace *, capable_ns)
37+
__field(int, cap)
38+
__field(int, ret)
39+
),
40+
41+
TP_fast_assign(
42+
__entry->cred = cred;
43+
__entry->target_ns = target_ns;
44+
__entry->capable_ns = ret == 0 ? capable_ns : NULL;
45+
__entry->cap = cap;
46+
__entry->ret = ret;
47+
),
48+
49+
TP_printk("cred %p, target_ns %p, capable_ns %p, cap %d, ret %d",
50+
__entry->cred, __entry->target_ns, __entry->capable_ns, __entry->cap,
51+
__entry->ret)
52+
);
53+
54+
#endif /* _TRACE_CAPABILITY_H */
55+
56+
/* This part must be outside protection */
57+
#include <trace/define_trace.h>

security/commoncap.c

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
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

14561478
static 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

Comments
 (0)