--- v16
+++ v26
@@ -1,300 +1,116 @@
-Change the security_cred_getsecid() interface to fill in a
-lsmblob instead of a u32 secid. The associated data elements
-in the audit sub-system are changed from a secid to a lsmblob
-to accommodate multiple possible LSM audit users.
+Change the security_inode_getsecid() interface to fill in a
+lsmblob structure instead of a u32 secid. This allows for its
+callers to gather data from all registered LSMs. Data is provided
+for IMA and audit.
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: John Johansen <john.johansen@canonical.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
-cc: linux-integrity@vger.kernel.org
+Cc: linux-integrity@vger.kernel.org
+Cc: linux-audit@redhat.com
---
- include/linux/security.h | 2 +-
- kernel/audit.c | 25 +++++++----------------
- kernel/audit.h | 5 +++--
- kernel/auditsc.c | 33 +++++++++++--------------------
- security/integrity/ima/ima_main.c | 8 ++++----
- security/security.c | 12 ++++++++---
- 6 files changed, 36 insertions(+), 49 deletions(-)
+ include/linux/security.h | 7 ++++---
+ kernel/auditsc.c | 6 +++++-
+ security/integrity/ima/ima_policy.c | 4 +---
+ security/security.c | 11 +++++++++--
+ 4 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
-index 3f07ba240ec5..9b4705d4ec2c 100644
+index 60f4515b9181..64f898e5e854 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
-@@ -459,7 +459,7 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
- void security_cred_free(struct cred *cred);
- int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
- void security_transfer_creds(struct cred *new, const struct cred *old);
--void security_cred_getsecid(const struct cred *c, u32 *secid);
-+void security_cred_getsecid(const struct cred *c, struct lsmblob *blob);
- int security_kernel_act_as(struct cred *new, struct lsmblob *blob);
- int security_kernel_create_files_as(struct cred *new, struct inode *inode);
- int security_kernel_module_request(char *kmod_name);
-diff --git a/kernel/audit.c b/kernel/audit.c
-index 1a7646854813..a7430f09afd9 100644
---- a/kernel/audit.c
-+++ b/kernel/audit.c
-@@ -125,7 +125,7 @@ static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
- /* The identity of the user shutting down the audit system. */
- kuid_t audit_sig_uid = INVALID_UID;
- pid_t audit_sig_pid = -1;
--u32 audit_sig_sid = 0;
-+struct lsmblob audit_sig_lsm;
+@@ -454,7 +454,7 @@ int security_inode_getsecurity(struct user_namespace *mnt_userns,
+ void **buffer, bool alloc);
+ int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
+ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
+-void security_inode_getsecid(struct inode *inode, u32 *secid);
++void security_inode_getsecid(struct inode *inode, struct lsmblob *blob);
+ int security_inode_copy_up(struct dentry *src, struct cred **new);
+ int security_inode_copy_up_xattr(const char *name);
+ int security_kernfs_init_security(struct kernfs_node *kn_dir,
+@@ -1005,9 +1005,10 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer,
+ return 0;
+ }
- /* Records can be lost in several ways:
- 0) [suppressed in audit_alloc]
-@@ -1419,29 +1419,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
- }
- case AUDIT_SIGNAL_INFO:
- len = 0;
-- if (audit_sig_sid) {
-- struct lsmblob blob;
--
-- /*
-- * lsmblob_init sets all values in the lsmblob
-- * to audit_sig_sid. This is temporary until
-- * audit_sig_sid is converted to a lsmblob, which
-- * happens later in this patch set.
-- */
-- lsmblob_init(&blob, audit_sig_sid);
-- err = security_secid_to_secctx(&blob, &ctx, &len);
-+ if (lsmblob_is_set(&audit_sig_lsm)) {
-+ err = security_secid_to_secctx(&audit_sig_lsm, &ctx,
-+ &len);
- if (err)
- return err;
- }
- sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
- if (!sig_data) {
-- if (audit_sig_sid)
-+ if (lsmblob_is_set(&audit_sig_lsm))
- security_release_secctx(ctx, len);
- return -ENOMEM;
- }
- sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
- sig_data->pid = audit_sig_pid;
-- if (audit_sig_sid) {
-+ if (lsmblob_is_set(&audit_sig_lsm)) {
- memcpy(sig_data->ctx, ctx, len);
- security_release_secctx(ctx, len);
- }
-@@ -2284,7 +2276,6 @@ int audit_set_loginuid(kuid_t loginuid)
- int audit_signal_info(int sig, struct task_struct *t)
+-static inline void security_inode_getsecid(struct inode *inode, u32 *secid)
++static inline void security_inode_getsecid(struct inode *inode,
++ struct lsmblob *blob)
{
- kuid_t uid = current_uid(), auid;
-- struct lsmblob blob;
+- *secid = 0;
++ lsmblob_init(blob, 0);
+ }
- if (auditd_test_task(t) &&
- (sig == SIGTERM || sig == SIGHUP ||
-@@ -2295,9 +2286,7 @@ int audit_signal_info(int sig, struct task_struct *t)
- audit_sig_uid = auid;
- else
- audit_sig_uid = uid;
-- security_task_getsecid(current, &blob);
-- /* scaffolding until audit_sig_sid is converted */
-- audit_sig_sid = blob.secid[0];
-+ security_task_getsecid(current, &audit_sig_lsm);
- }
-
- return audit_signal_info_syscall(t);
-diff --git a/kernel/audit.h b/kernel/audit.h
-index 6fb7160412d4..f65f516913c6 100644
---- a/kernel/audit.h
-+++ b/kernel/audit.h
-@@ -9,6 +9,7 @@
- #include <linux/fs.h>
- #include <linux/audit.h>
- #include <linux/skbuff.h>
-+#include <linux/security.h>
- #include <uapi/linux/mqueue.h>
- #include <linux/tty.h>
-
-@@ -134,7 +135,7 @@ struct audit_context {
- kuid_t target_auid;
- kuid_t target_uid;
- unsigned int target_sessionid;
-- u32 target_sid;
-+ struct lsmblob target_lsm;
- char target_comm[TASK_COMM_LEN];
-
- struct audit_tree_refs *trees, *first_trees;
-@@ -329,7 +330,7 @@ extern char *audit_unpack_string(void **bufp, size_t *remain, size_t len);
-
- extern pid_t audit_sig_pid;
- extern kuid_t audit_sig_uid;
--extern u32 audit_sig_sid;
-+extern struct lsmblob audit_sig_lsm;
-
- extern int audit_filter(int msgtype, unsigned int listtype);
-
+ static inline int security_inode_copy_up(struct dentry *src, struct cred **new)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
-index 5d4ce44bff91..97da8bf2eda9 100644
+index dd902b68433e..6684927f12fc 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
-@@ -112,7 +112,7 @@ struct audit_aux_data_pids {
- kuid_t target_auid[AUDIT_AUX_PIDS];
- kuid_t target_uid[AUDIT_AUX_PIDS];
- unsigned int target_sessionid[AUDIT_AUX_PIDS];
-- u32 target_sid[AUDIT_AUX_PIDS];
-+ struct lsmblob target_lsm[AUDIT_AUX_PIDS];
- char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
- int pid_count;
- };
-@@ -964,14 +964,14 @@ static inline void audit_free_context(struct audit_context *context)
- }
+@@ -1962,13 +1962,17 @@ static void audit_copy_inode(struct audit_names *name,
+ const struct dentry *dentry,
+ struct inode *inode, unsigned int flags)
+ {
++ struct lsmblob blob;
++
+ name->ino = inode->i_ino;
+ name->dev = inode->i_sb->s_dev;
+ name->mode = inode->i_mode;
+ name->uid = inode->i_uid;
+ name->gid = inode->i_gid;
+ name->rdev = inode->i_rdev;
+- security_inode_getsecid(inode, &name->osid);
++ security_inode_getsecid(inode, &blob);
++ /* scaffolding until osid is updated */
++ name->osid = blob.secid[0];
+ if (flags & AUDIT_INODE_NOEVAL) {
+ name->fcap_ver = -1;
+ return;
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index a05841e1012b..5ee7629fd782 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -606,7 +606,6 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
+ return false;
+ for (i = 0; i < MAX_LSM_RULES; i++) {
+ int rc = 0;
+- u32 osid;
+ struct lsmblob lsmdata;
- static int audit_log_pid_context(struct audit_context *context, pid_t pid,
-- kuid_t auid, kuid_t uid, unsigned int sessionid,
-- u32 sid, char *comm)
-+ kuid_t auid, kuid_t uid,
-+ unsigned int sessionid,
-+ struct lsmblob *blob, char *comm)
- {
- struct audit_buffer *ab;
- char *ctx = NULL;
- u32 len;
- int rc = 0;
-- struct lsmblob blob;
-
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
- if (!ab)
-@@ -980,9 +980,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
- audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid,
- from_kuid(&init_user_ns, auid),
- from_kuid(&init_user_ns, uid), sessionid);
-- if (sid) {
-- lsmblob_init(&blob, sid);
-- if (security_secid_to_secctx(&blob, &ctx, &len)) {
-+ if (lsmblob_is_set(blob)) {
-+ if (security_secid_to_secctx(blob, &ctx, &len)) {
- audit_log_format(ab, " obj=(none)");
- rc = 1;
- } else {
-@@ -1553,7 +1552,7 @@ static void audit_log_exit(void)
- axs->target_auid[i],
- axs->target_uid[i],
- axs->target_sessionid[i],
-- axs->target_sid[i],
-+ &axs->target_lsm[i],
- axs->target_comm[i]))
- call_panic = 1;
- }
-@@ -1562,7 +1561,7 @@ static void audit_log_exit(void)
- audit_log_pid_context(context, context->target_pid,
- context->target_auid, context->target_uid,
- context->target_sessionid,
-- context->target_sid, context->target_comm))
-+ &context->target_lsm, context->target_comm))
- call_panic = 1;
-
- if (context->pwd.dentry && context->pwd.mnt) {
-@@ -1740,7 +1739,7 @@ void __audit_syscall_exit(int success, long return_code)
- context->aux = NULL;
- context->aux_pids = NULL;
- context->target_pid = 0;
-- context->target_sid = 0;
-+ lsmblob_init(&context->target_lsm, 0);
- context->sockaddr_len = 0;
- context->type = 0;
- context->fds[0] = -1;
-@@ -2393,15 +2392,12 @@ int __audit_sockaddr(int len, void *a)
- void __audit_ptrace(struct task_struct *t)
- {
- struct audit_context *context = audit_context();
-- struct lsmblob blob;
-
- context->target_pid = task_tgid_nr(t);
- context->target_auid = audit_get_loginuid(t);
- context->target_uid = task_uid(t);
- context->target_sessionid = audit_get_sessionid(t);
-- security_task_getsecid(t, &blob);
-- /* scaffolding - until target_sid is converted */
-- context->target_sid = blob.secid[0];
-+ security_task_getsecid(t, &context->target_lsm);
- memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
- }
-
-@@ -2417,7 +2413,6 @@ int audit_signal_info_syscall(struct task_struct *t)
- struct audit_aux_data_pids *axp;
- struct audit_context *ctx = audit_context();
- kuid_t t_uid = task_uid(t);
-- struct lsmblob blob;
-
- if (!audit_signals || audit_dummy_context())
- return 0;
-@@ -2429,9 +2424,7 @@ int audit_signal_info_syscall(struct task_struct *t)
- ctx->target_auid = audit_get_loginuid(t);
- ctx->target_uid = t_uid;
- ctx->target_sessionid = audit_get_sessionid(t);
-- security_task_getsecid(t, &blob);
-- /* scaffolding until target_sid is converted */
-- ctx->target_sid = blob.secid[0];
-+ security_task_getsecid(t, &ctx->target_lsm);
- memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
- return 0;
- }
-@@ -2452,9 +2445,7 @@ int audit_signal_info_syscall(struct task_struct *t)
- axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
- axp->target_uid[axp->pid_count] = t_uid;
- axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
-- security_task_getsecid(t, &blob);
-- /* scaffolding until target_sid is converted */
-- axp->target_sid[axp->pid_count] = blob.secid[0];
-+ security_task_getsecid(t, &axp->target_lsm[axp->pid_count]);
- memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
- axp->pid_count++;
-
-diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
-index 1f50f68a6f5b..8ad399ea7883 100644
---- a/security/integrity/ima/ima_main.c
-+++ b/security/integrity/ima/ima_main.c
-@@ -412,7 +412,6 @@ int ima_file_mmap(struct file *file, unsigned long prot)
- int ima_bprm_check(struct linux_binprm *bprm)
- {
- int ret;
-- u32 secid;
- struct lsmblob blob;
-
- security_task_getsecid(current, &blob);
-@@ -422,9 +421,10 @@ int ima_bprm_check(struct linux_binprm *bprm)
- if (ret)
- return ret;
-
-- security_cred_getsecid(bprm->cred, &secid);
-- return process_measurement(bprm->file, bprm->cred, secid, NULL, 0,
-- MAY_EXEC, CREDS_CHECK);
-+ security_cred_getsecid(bprm->cred, &blob);
-+ /* scaffolding until process_measurement changes */
-+ return process_measurement(bprm->file, bprm->cred, blob.secid[0],
-+ NULL, 0, MAY_EXEC, CREDS_CHECK);
- }
-
- /**
+ if (!ima_lsm_isset(rule, i)) {
+@@ -619,8 +618,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
+ case LSM_OBJ_USER:
+ case LSM_OBJ_ROLE:
+ case LSM_OBJ_TYPE:
+- security_inode_getsecid(inode, &osid);
+- lsmblob_init(&lsmdata, osid);
++ security_inode_getsecid(inode, &lsmdata);
+ rc = ima_filter_rule_match(&lsmdata, rule->lsm[i].type,
+ Audit_equal,
+ rule->lsm[i].rule);
diff --git a/security/security.c b/security/security.c
-index 8cced3fc9ad3..bf71066ea19b 100644
+index f3b985f76dab..54f4a4ead69f 100644
--- a/security/security.c
+++ b/security/security.c
-@@ -1647,10 +1647,16 @@ void security_transfer_creds(struct cred *new, const struct cred *old)
- call_void_hook(cred_transfer, new, old);
+@@ -1546,9 +1546,16 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
}
+ EXPORT_SYMBOL(security_inode_listsecurity);
--void security_cred_getsecid(const struct cred *c, u32 *secid)
-+void security_cred_getsecid(const struct cred *c, struct lsmblob *blob)
+-void security_inode_getsecid(struct inode *inode, u32 *secid)
++void security_inode_getsecid(struct inode *inode, struct lsmblob *blob)
{
-- *secid = 0;
-- call_void_hook(cred_getsecid, c, secid);
+- call_void_hook(inode_getsecid, inode, secid);
+ struct security_hook_list *hp;
+
+ lsmblob_init(blob, 0);
-+ hlist_for_each_entry(hp, &security_hook_heads.cred_getsecid, list) {
++ hlist_for_each_entry(hp, &security_hook_heads.inode_getsecid, list) {
+ if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot))
+ continue;
-+ hp->hook.cred_getsecid(c, &blob->secid[hp->lsmid->slot]);
++ hp->hook.inode_getsecid(inode, &blob->secid[hp->lsmid->slot]);
+ }
}
- EXPORT_SYMBOL(security_cred_getsecid);
+ int security_inode_copy_up(struct dentry *src, struct cred **new)
--
-2.24.1
+2.29.2