From: Jordan Rome <linux@jordanrome.com>
To: linux-security-module@vger.kernel.org
Cc: linux-trace-kernel@vger.kernel.org,
Andrii Nakryiko <andrii@kernel.org>,
Kernel Team <kernel-team@fb.com>, Serge Hallyn <serge@hallyn.com>,
Yonghong Song <yonghong.song@linux.dev>
Subject: [v2] security: add trace event for cap_capable
Date: Fri, 25 Oct 2024 08:11:28 -0700 [thread overview]
Message-ID: <20241025151128.1854905-1-linux@jordanrome.com> (raw)
In cases where we want a stable way to observe/trace
cap_capable (e.g. protection from inlining and API updates)
add a tracepoint that passes:
- The credentials used
- The user namespace of the resource being accessed
- The user namespace that has the capability to access the
targeted resource
- The capability to check for
- Bitmask of options defined in include/linux/security.h
- The return value of the check
Signed-off-by: Jordan Rome <linux@jordanrome.com>
---
MAINTAINERS | 1 +
include/trace/events/capability.h | 60 +++++++++++++++++++++++++++++++
security/commoncap.c | 31 +++++++++++-----
3 files changed, 84 insertions(+), 8 deletions(-)
create mode 100644 include/trace/events/capability.h
diff --git a/MAINTAINERS b/MAINTAINERS
index cc40a9d9b8cd..210e9076c858 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4994,6 +4994,7 @@ M: Serge Hallyn <serge@hallyn.com>
L: linux-security-module@vger.kernel.org
S: Supported
F: include/linux/capability.h
+F: include/trace/events/capability.h
F: include/uapi/linux/capability.h
F: kernel/capability.c
F: security/commoncap.c
diff --git a/include/trace/events/capability.h b/include/trace/events/capability.h
new file mode 100644
index 000000000000..e706ce690c38
--- /dev/null
+++ b/include/trace/events/capability.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM capability
+
+#if !defined(_TRACE_CAPABILITY_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_CAPABILITY_H
+
+#include <linux/cred.h>
+#include <linux/tracepoint.h>
+#include <linux/user_namespace.h>
+
+/**
+ * cap_capable - called after it's determined if a task has a particular
+ * effective capability
+ *
+ * @cred: The credentials used
+ * @targ_ns: The user namespace of the resource being accessed
+ * @capable_ns: The user namespace in which the credential provides the
+ * capability to access the targeted resource.
+ * This will be NULL if ret is not 0.
+ * @cap: The capability to check for
+ * @opts: Bitmask of options defined in include/linux/security.h
+ * @ret: The return value of the check: 0 if it does, -ve if it does not
+ *
+ * Allows to trace calls to cap_capable in commoncap.c
+ */
+TRACE_EVENT(cap_capable,
+
+ TP_PROTO(const struct cred *cred, struct user_namespace *targ_ns,
+ struct user_namespace *capable_ns, int cap, unsigned int opts, int ret),
+
+ TP_ARGS(cred, targ_ns, capable_ns, cap, opts, ret),
+
+ TP_STRUCT__entry(
+ __field(const struct cred *, cred)
+ __field(struct user_namespace *, targ_ns)
+ __field(struct user_namespace *, capable_ns)
+ __field(int, cap)
+ __field(unsigned int, opts)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ __entry->cred = cred;
+ __entry->targ_ns = targ_ns;
+ __entry->capable_ns = capable_ns;
+ __entry->cap = cap;
+ __entry->opts = opts;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("cred %p, targ_ns %p, capable_ns %p, cap %d, opts %u, ret %d",
+ __entry->cred, __entry->targ_ns, __entry->capable_ns, __entry->cap,
+ __entry->opts, __entry->ret)
+);
+
+#endif /* _TRACE_CAPABILITY_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/security/commoncap.c b/security/commoncap.c
index 162d96b3a676..12c3ddfe0d6e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -27,6 +27,9 @@
#include <linux/mnt_idmapping.h>
#include <uapi/linux/lsm.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/capability.h>
+
/*
* If a non-root user executes a setuid-root binary in
* !secure(SECURE_NOROOT) mode, then we raise capabilities.
@@ -52,7 +55,7 @@ static void warn_setuid_and_fcaps_mixed(const char *fname)
/**
* cap_capable - Determine whether a task has a particular effective capability
* @cred: The credentials to use
- * @targ_ns: The user namespace in which we need the capability
+ * @targ_ns: The user namespace of the resource being accessed
* @cap: The capability to check for
* @opts: Bitmask of options defined in include/linux/security.h
*
@@ -68,6 +71,7 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
int cap, unsigned int opts)
{
struct user_namespace *ns = targ_ns;
+ int ret = -EPERM;
/* See if cred has the capability in the target user namespace
* by examining the target user namespace and all of the target
@@ -75,22 +79,32 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
*/
for (;;) {
/* Do we have the necessary capabilities? */
- if (ns == cred->user_ns)
- return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
+ if (ns == cred->user_ns) {
+ if (cap_raised(cred->cap_effective, cap))
+ ret = 0;
+ else
+ ns = NULL;
+ break;
+ }
/*
* If we're already at a lower level than we're looking for,
* we're done searching.
*/
- if (ns->level <= cred->user_ns->level)
- return -EPERM;
+ if (ns->level <= cred->user_ns->level) {
+ ns = NULL;
+ break;
+ }
/*
* The owner of the user namespace in the parent of the
* user namespace has all caps.
*/
- if ((ns->parent == cred->user_ns) && uid_eq(ns->owner, cred->euid))
- return 0;
+ if ((ns->parent == cred->user_ns) && uid_eq(ns->owner, cred->euid)) {
+ ns = ns->parent;
+ ret = 0;
+ break;
+ }
/*
* If you have a capability in a parent user ns, then you have
@@ -99,7 +113,8 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
ns = ns->parent;
}
- /* We never get here */
+ trace_cap_capable(cred, targ_ns, ns, cap, opts, ret);
+ return ret;
}
/**
--
2.43.5
next reply other threads:[~2024-10-25 15:12 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-25 15:11 Jordan Rome [this message]
2024-10-25 18:37 ` [v2] security: add trace event for cap_capable Andrii Nakryiko
2024-10-25 19:52 ` Serge E. Hallyn
2024-10-25 20:24 ` Jordan Rome
2024-10-26 10:09 ` Serge E. Hallyn
2024-10-26 11:22 ` Jordan Rome
2024-10-26 13:00 ` Serge E. Hallyn
2024-10-27 18:21 ` Jordan Rome
2024-10-28 16:51 ` sergeh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241025151128.1854905-1-linux@jordanrome.com \
--to=linux@jordanrome.com \
--cc=andrii@kernel.org \
--cc=kernel-team@fb.com \
--cc=linux-security-module@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=serge@hallyn.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.