From: Casey Schaufler <casey@schaufler-ca.com>
To: casey@schaufler-ca.com, paul@paul-moore.com,
linux-security-module@vger.kernel.org
Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org,
john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp,
stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org,
mic@digikod.net
Subject: [PATCH 03/13] LSM: Add lsmblob_to_secctx hook
Date: Sun, 25 Aug 2024 12:00:38 -0700 [thread overview]
Message-ID: <20240825190048.13289-4-casey@schaufler-ca.com> (raw)
In-Reply-To: <20240825190048.13289-1-casey@schaufler-ca.com>
Add a new hook security_lsmblob_to_secctx() and its LSM specific
implementations. The LSM specific code will use the lsmblob element
allocated for that module. This allows for the possibility that more
than one module may be called upon to translate a secid to a string,
as can occur in the audit code.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hook_defs.h | 2 ++
include/linux/security.h | 11 +++++++++-
security/apparmor/include/secid.h | 2 ++
security/apparmor/lsm.c | 1 +
security/apparmor/secid.c | 36 +++++++++++++++++++++++++++++++
security/security.c | 30 ++++++++++++++++++++++++++
security/selinux/hooks.c | 16 ++++++++++++--
security/smack/smack_lsm.c | 31 +++++++++++++++++++++-----
8 files changed, 121 insertions(+), 8 deletions(-)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 1d3bdf71109e..3e5f6baa7b9f 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -291,6 +291,8 @@ LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)
LSM_HOOK(int, 0, ismaclabel, const char *name)
LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata,
u32 *seclen)
+LSM_HOOK(int, -EOPNOTSUPP, lsmblob_to_secctx, struct lsmblob *blob,
+ char **secdata, u32 *seclen)
LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid)
LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen)
LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode)
diff --git a/include/linux/security.h b/include/linux/security.h
index c0ed2119a622..457fafc32fb0 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -520,6 +520,8 @@ int security_setprocattr(int lsmid, const char *name, void *value, size_t size);
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
int security_ismaclabel(const char *name);
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_lsmblob_to_secctx(struct lsmblob *blob, char **secdata,
+ u32 *seclen);
int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
void security_release_secctx(char *secdata, u32 seclen);
void security_inode_invalidate_secctx(struct inode *inode);
@@ -1461,7 +1463,14 @@ static inline int security_ismaclabel(const char *name)
return 0;
}
-static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+static inline int security_secid_to_secctx(u32 secid, char **secdata,
+ u32 *seclen)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int security_lsmblob_to_secctx(struct lsmblob *blob,
+ char **secdata, u32 *seclen)
{
return -EOPNOTSUPP;
}
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
index a912a5d5d04f..816a425e2023 100644
--- a/security/apparmor/include/secid.h
+++ b/security/apparmor/include/secid.h
@@ -26,6 +26,8 @@ extern int apparmor_display_secid_mode;
struct aa_label *aa_secid_to_label(u32 secid);
int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int apparmor_lsmblob_to_secctx(struct lsmblob *blob, char **secdata,
+ u32 *seclen);
int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
void apparmor_release_secctx(char *secdata, u32 seclen);
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 808060f9effb..050d103f5ca5 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1532,6 +1532,7 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
#endif
LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx),
+ LSM_HOOK_INIT(lsmblob_to_secctx, apparmor_lsmblob_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid),
LSM_HOOK_INIT(release_secctx, apparmor_release_secctx),
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index 83d3d1e6d9dc..3c389e5810cd 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -90,6 +90,42 @@ int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
return 0;
}
+int apparmor_lsmblob_to_secctx(struct lsmblob *blob, char **secdata,
+ u32 *seclen)
+{
+ /* TODO: cache secctx and ref count so we don't have to recreate */
+ struct aa_label *label;
+ int flags = FLAG_VIEW_SUBNS | FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT;
+ int len;
+
+ AA_BUG(!seclen);
+
+ /* scaffolding */
+ if (!blob->apparmor.label && blob->scaffold.secid)
+ label = aa_secid_to_label(blob->scaffold.secid);
+ else
+ label = blob->apparmor.label;
+
+ if (!label)
+ return -EINVAL;
+
+ if (apparmor_display_secid_mode)
+ flags |= FLAG_SHOW_MODE;
+
+ if (secdata)
+ len = aa_label_asxprint(secdata, root_ns, label,
+ flags, GFP_ATOMIC);
+ else
+ len = aa_label_snxprint(NULL, 0, root_ns, label, flags);
+
+ if (len < 0)
+ return -ENOMEM;
+
+ *seclen = len;
+
+ return 0;
+}
+
int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
{
struct aa_label *label;
diff --git a/security/security.c b/security/security.c
index 64a6d6bbd1f4..bb541a3be410 100644
--- a/security/security.c
+++ b/security/security.c
@@ -4192,6 +4192,36 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
}
EXPORT_SYMBOL(security_secid_to_secctx);
+/**
+ * security_lsmblob_to_secctx() - Convert a lsmblob to a secctx
+ * @blob: lsm specific information
+ * @secdata: secctx
+ * @seclen: secctx length
+ *
+ * Convert a @blob entry to security context. If @secdata is NULL the
+ * length of the result will be returned in @seclen, but no @secdata
+ * will be returned. This does mean that the length could change between
+ * calls to check the length and the next call which actually allocates
+ * and returns the @secdata.
+ *
+ * Return: Return 0 on success, error on failure.
+ */
+int security_lsmblob_to_secctx(struct lsmblob *blob, char **secdata,
+ u32 *seclen)
+{
+ struct security_hook_list *hp;
+ int rc;
+
+ hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) {
+ rc = hp->hook.lsmblob_to_secctx(blob, secdata, seclen);
+ if (rc != LSM_RET_DEFAULT(secid_to_secctx))
+ return rc;
+ }
+
+ return LSM_RET_DEFAULT(secid_to_secctx);
+}
+EXPORT_SYMBOL(security_lsmblob_to_secctx);
+
/**
* security_secctx_to_secid() - Convert a secctx to a secid
* @secdata: secctx
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 55c78c318ccd..102489e6d579 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6610,8 +6610,19 @@ static int selinux_ismaclabel(const char *name)
static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
{
- return security_sid_to_context(secid,
- secdata, seclen);
+ return security_sid_to_context(secid, secdata, seclen);
+}
+
+static int selinux_lsmblob_to_secctx(struct lsmblob *blob, char **secdata,
+ u32 *seclen)
+{
+ u32 secid = blob->selinux.secid;
+
+ /* scaffolding */
+ if (!secid)
+ secid = blob->scaffold.secid;
+
+ return security_sid_to_context(secid, secdata, seclen);
}
static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
@@ -7388,6 +7399,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
+ LSM_HOOK_INIT(lsmblob_to_secctx, selinux_lsmblob_to_secctx),
LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 52d5ef986db8..5d74d8590862 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4787,7 +4787,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
static int smack_audit_rule_match(struct lsmblob *blob, u32 field, u32 op,
void *vrule)
{
- struct smack_known *skp;
+ struct smack_known *skp = blob->smack.skp;
char *rule = vrule;
if (unlikely(!rule)) {
@@ -4799,10 +4799,8 @@ static int smack_audit_rule_match(struct lsmblob *blob, u32 field, u32 op,
return 0;
/* scaffolding */
- if (!blob->smack.skp && blob->scaffold.secid)
+ if (!skp && blob->scaffold.secid)
skp = smack_from_secid(blob->scaffold.secid);
- else
- skp = blob->smack.skp;
/*
* No need to do string comparisons. If a match occurs,
@@ -4833,7 +4831,6 @@ static int smack_ismaclabel(const char *name)
return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
}
-
/**
* smack_secid_to_secctx - return the smack label for a secid
* @secid: incoming integer
@@ -4852,6 +4849,29 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
return 0;
}
+/**
+ * smack_lsmblob_to_secctx - return the smack label
+ * @blob: includes incoming Smack data
+ * @secdata: destination
+ * @seclen: how long it is
+ *
+ * Exists for audit code.
+ */
+static int smack_lsmblob_to_secctx(struct lsmblob *blob, char **secdata,
+ u32 *seclen)
+{
+ struct smack_known *skp = blob->smack.skp;
+
+ /* scaffolding */
+ if (!skp && blob->scaffold.secid)
+ skp = smack_from_secid(blob->scaffold.secid);
+
+ if (secdata)
+ *secdata = skp->smk_known;
+ *seclen = strlen(skp->smk_known);
+ return 0;
+}
+
/**
* smack_secctx_to_secid - return the secid for a smack label
* @secdata: smack label
@@ -5208,6 +5228,7 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
+ LSM_HOOK_INIT(lsmblob_to_secctx, smack_lsmblob_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
--
2.41.0
next prev parent reply other threads:[~2024-08-25 19:02 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20240825190048.13289-1-casey.ref@schaufler-ca.com>
2024-08-25 19:00 ` [PATCH 00/13] LSM: Move away from secids Casey Schaufler
2024-08-25 19:00 ` [PATCH 01/13] LSM: Add the lsmblob data structure Casey Schaufler
2024-08-26 13:34 ` Georgia Garcia
2024-08-25 19:00 ` [PATCH 02/13] LSM: Use lsmblob in security_audit_rule_match Casey Schaufler
2024-08-26 19:31 ` kernel test robot
2024-08-25 19:00 ` Casey Schaufler [this message]
2024-08-26 17:43 ` [PATCH 03/13] LSM: Add lsmblob_to_secctx hook Georgia Garcia
2024-08-26 18:45 ` Casey Schaufler
2024-08-27 14:45 ` Georgia Garcia
2024-08-25 19:00 ` [PATCH 04/13] Audit: maintain an lsmblob in audit_context Casey Schaufler
2024-08-27 15:01 ` Georgia Garcia
2024-08-27 15:08 ` Georgia Garcia
2024-08-25 19:00 ` [PATCH 05/13] LSM: Use lsmblob in security_ipc_getsecid Casey Schaufler
2024-08-27 12:23 ` Stephen Smalley
2024-08-25 19:00 ` [PATCH 06/13] Audit: Update shutdown LSM data Casey Schaufler
2024-08-25 19:00 ` [PATCH 07/13] LSM: Use lsmblob in security_current_getsecid Casey Schaufler
2024-08-26 21:24 ` kernel test robot
2024-08-25 19:00 ` [PATCH 08/13] LSM: Use lsmblob in security_inode_getsecid Casey Schaufler
2024-08-25 19:00 ` [PATCH 09/13] Audit: use an lsmblob in audit_names Casey Schaufler
2024-08-25 19:00 ` [PATCH 10/13] LSM: Create new security_cred_getlsmblob LSM hook Casey Schaufler
2024-08-27 5:00 ` kernel test robot
2024-08-25 19:00 ` [PATCH 11/13] Audit: Change context data from secid to lsmblob Casey Schaufler
2024-08-25 19:00 ` [PATCH 12/13] Netlabel: Use lsmblob for audit data Casey Schaufler
2024-08-25 19:00 ` [PATCH 13/13] LSM: Remove lsmblob scaffolding Casey Schaufler
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=20240825190048.13289-4-casey@schaufler-ca.com \
--to=casey@schaufler-ca.com \
--cc=jmorris@namei.org \
--cc=john.johansen@canonical.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=mic@digikod.net \
--cc=paul@paul-moore.com \
--cc=penguin-kernel@i-love.sakura.ne.jp \
--cc=serge@hallyn.com \
--cc=stephen.smalley.work@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox