--- v35
+++ v8
@@ -1,243 +1,71 @@
-Create a new audit record AUDIT_MAC_OBJ_CONTEXTS.
-An example of the MAC_OBJ_CONTEXTS (1421) record is:
-
- type=MAC_OBJ_CONTEXTS[1421]
- msg=audit(1601152467.009:1050):
- obj_selinux=unconfined_u:object_r:user_home_t:s0
-
-When an audit event includes a AUDIT_MAC_OBJ_CONTEXTS record
-the "obj=" field in other records in the event will be "obj=?".
-An AUDIT_MAC_OBJ_CONTEXTS record is supplied when the system has
-multiple security modules that may make access decisions based
-on an object security context.
+Add an entry /proc/.../attr/context which displays the full
+process security "context" in compound format:'
+ lsm1\0value\0lsm2\0value\0...
+This entry is not writable.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
- include/linux/audit.h | 5 +++
- include/uapi/linux/audit.h | 1 +
- kernel/audit.c | 47 +++++++++++++++++++++++
- kernel/auditsc.c | 79 ++++++++++++--------------------------
- 4 files changed, 77 insertions(+), 55 deletions(-)
+ fs/proc/base.c | 1 +
+ security/security.c | 27 +++++++++++++++++++++++++++
+ 2 files changed, 28 insertions(+)
-diff --git a/include/linux/audit.h b/include/linux/audit.h
-index 14849d5f84b4..1b05eb2dbe77 100644
---- a/include/linux/audit.h
-+++ b/include/linux/audit.h
-@@ -191,6 +191,8 @@ extern void audit_log_path_denied(int type,
- const char *operation);
- extern void audit_log_lost(const char *message);
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 7bf70e041315..79600df5f7a2 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2619,6 +2619,7 @@ static const struct pid_entry attr_dir_stuff[] = {
+ ATTR(NULL, "keycreate", 0666),
+ ATTR(NULL, "sockcreate", 0666),
+ ATTR(NULL, "display", 0666),
++ ATTR(NULL, "context", 0666),
+ #ifdef CONFIG_SECURITY_SMACK
+ DIR("smack", 0555,
+ proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops),
+diff --git a/security/security.c b/security/security.c
+index 8cb91f33c166..d151ac4a398b 100644
+--- a/security/security.c
++++ b/security/security.c
+@@ -2082,6 +2082,10 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name,
+ char **value)
+ {
+ struct security_hook_list *hp;
++ char *final = NULL;
++ char *cp;
++ int rc = 0;
++ int finallen = 0;
+ int display = lsm_task_display(current);
+ int slot = 0;
-+extern void audit_log_object_context(struct audit_buffer *ab,
-+ struct lsmblob *blob);
- extern int audit_log_task_context(struct audit_buffer *ab);
- extern void audit_log_task_info(struct audit_buffer *ab);
+@@ -2099,6 +2103,29 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name,
+ return -ENOMEM;
+ }
-@@ -251,6 +253,9 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
- { }
- static inline void audit_log_path_denied(int type, const char *operation)
- { }
-+static inline void audit_log_object_context(struct audit_buffer *ab,
-+ struct lsmblob *blob)
-+{ }
- static inline int audit_log_task_context(struct audit_buffer *ab)
- {
- return 0;
-diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
-index af0aaccfaf57..d25d76b29e3c 100644
---- a/include/uapi/linux/audit.h
-+++ b/include/uapi/linux/audit.h
-@@ -144,6 +144,7 @@
- #define AUDIT_MAC_CALIPSO_ADD 1418 /* NetLabel: add CALIPSO DOI entry */
- #define AUDIT_MAC_CALIPSO_DEL 1419 /* NetLabel: del CALIPSO DOI entry */
- #define AUDIT_MAC_TASK_CONTEXTS 1420 /* Multiple LSM task contexts */
-+#define AUDIT_MAC_OBJ_CONTEXTS 1421 /* Multiple LSM objext contexts */
-
- #define AUDIT_FIRST_KERN_ANOM_MSG 1700
- #define AUDIT_LAST_KERN_ANOM_MSG 1799
-diff --git a/kernel/audit.c b/kernel/audit.c
-index 8ed2d717c217..a8c3ec6ba60b 100644
---- a/kernel/audit.c
-+++ b/kernel/audit.c
-@@ -2226,6 +2226,53 @@ static void audit_buffer_aux_end(struct audit_buffer *ab)
- ab->skb = skb_peek(&ab->skb_list);
- }
-
-+void audit_log_object_context(struct audit_buffer *ab, struct lsmblob *blob)
-+{
-+ int i;
-+ int error;
-+ struct lsmcontext context;
-+
-+ if (!lsm_multiple_contexts()) {
-+ error = security_secid_to_secctx(blob, &context, LSMBLOB_FIRST);
-+ if (error) {
-+ if (error != -EINVAL)
-+ goto error_path;
-+ return;
-+ }
-+ audit_log_format(ab, " obj=%s", context.context);
-+ security_release_secctx(&context);
-+ } else {
-+ audit_log_format(ab, " obj=?");
-+ error = audit_buffer_aux_new(ab, AUDIT_MAC_OBJ_CONTEXTS);
-+ if (error)
-+ goto error_path;
-+
-+ for (i = 0; i < LSMBLOB_ENTRIES; i++) {
-+ if (blob->secid[i] == 0)
++ if (!strcmp(name, "context")) {
++ hlist_for_each_entry(hp, &security_hook_heads.getprocattr,
++ list) {
++ rc = hp->hook.getprocattr(p, "current", &cp);
++ if (rc == -EINVAL || rc == -ENOPROTOOPT)
+ continue;
-+ error = security_secid_to_secctx(blob, &context, i);
-+ if (error) {
-+ audit_log_format(ab, "%sobj_%s=?",
-+ i ? " " : "",
-+ lsm_slot_to_name(i));
-+ if (error != -EINVAL)
-+ audit_panic("error in audit_log_object_context");
-+ } else {
-+ audit_log_format(ab, "%sobj_%s=%s",
-+ i ? " " : "",
-+ lsm_slot_to_name(i),
-+ context.context);
-+ security_release_secctx(&context);
++ if (rc < 0) {
++ kfree(final);
++ return rc;
++ }
++ rc = append_ctx(&final, &finallen, hp->lsmid->lsm,
++ cp, rc);
++ if (rc < 0) {
++ kfree(final);
++ return rc;
+ }
+ }
-+
-+ audit_buffer_aux_end(ab);
-+ }
-+ return;
-+
-+error_path:
-+ audit_panic("error in audit_log_object_context");
-+}
-
- int audit_log_task_context(struct audit_buffer *ab)
- {
-diff --git a/kernel/auditsc.c b/kernel/auditsc.c
-index 557713954a69..04bf3c04ef3d 100644
---- a/kernel/auditsc.c
-+++ b/kernel/auditsc.c
-@@ -1114,36 +1114,25 @@ static inline void audit_free_context(struct audit_context *context)
- kfree(context);
- }
-
--static int audit_log_pid_context(struct audit_context *context, pid_t pid,
-- kuid_t auid, kuid_t uid,
-- unsigned int sessionid,
-- struct lsmblob *blob, char *comm)
-+static void audit_log_pid_context(struct audit_context *context, pid_t pid,
-+ kuid_t auid, kuid_t uid,
-+ unsigned int sessionid,
-+ struct lsmblob *blob, char *comm)
- {
- struct audit_buffer *ab;
-- struct lsmcontext lsmctx;
-- int rc = 0;
-
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
- if (!ab)
-- return rc;
-+ return;
-
- 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 (lsmblob_is_set(blob)) {
-- if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) {
-- audit_log_format(ab, " obj=(none)");
-- rc = 1;
-- } else {
-- audit_log_format(ab, " obj=%s", lsmctx.context);
-- security_release_secctx(&lsmctx);
-- }
-- }
-+ if (lsmblob_is_set(blob))
-+ audit_log_object_context(ab, blob);
- audit_log_format(ab, " ocomm=");
- audit_log_untrustedstring(ab, comm);
- audit_log_end(ab);
--
-- return rc;
- }
-
- static void audit_log_execve_info(struct audit_context *context,
-@@ -1420,18 +1409,10 @@ static void show_special(struct audit_context *context, int *call_panic)
- from_kgid(&init_user_ns, context->ipc.gid),
- context->ipc.mode);
- if (osid) {
-- struct lsmcontext lsmcxt;
- struct lsmblob blob;
-
- lsmblob_init(&blob, osid);
-- if (security_secid_to_secctx(&blob, &lsmcxt,
-- LSMBLOB_FIRST)) {
-- audit_log_format(ab, " osid=%u", osid);
-- *call_panic = 1;
-- } else {
-- audit_log_format(ab, " obj=%s", lsmcxt.context);
-- security_release_secctx(&lsmcxt);
-- }
-+ audit_log_object_context(ab, &blob);
- }
- if (context->ipc.has_perm) {
- audit_log_end(ab);
-@@ -1588,19 +1569,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
- from_kgid(&init_user_ns, n->gid),
- MAJOR(n->rdev),
- MINOR(n->rdev));
-- if (lsmblob_is_set(&n->lsmblob)) {
-- struct lsmcontext lsmctx;
--
-- if (security_secid_to_secctx(&n->lsmblob, &lsmctx,
-- LSMBLOB_FIRST)) {
-- audit_log_format(ab, " osid=?");
-- if (call_panic)
-- *call_panic = 2;
-- } else {
-- audit_log_format(ab, " obj=%s", lsmctx.context);
-- security_release_secctx(&lsmctx);
-- }
-- }
-+ if (lsmblob_is_set(&n->lsmblob))
-+ audit_log_object_context(ab, &n->lsmblob);
-
- /* log the audit_names record type */
- switch (n->type) {
-@@ -1805,21 +1775,20 @@ static void audit_log_exit(void)
- struct audit_aux_data_pids *axs = (void *)aux;
-
- for (i = 0; i < axs->pid_count; i++)
-- if (audit_log_pid_context(context, axs->target_pid[i],
-- axs->target_auid[i],
-- axs->target_uid[i],
-- axs->target_sessionid[i],
-- &axs->target_lsm[i],
-- axs->target_comm[i]))
-- call_panic = 1;
-- }
--
-- if (context->target_pid &&
-- audit_log_pid_context(context, context->target_pid,
-- context->target_auid, context->target_uid,
-- context->target_sessionid,
-- &context->target_lsm, context->target_comm))
-- call_panic = 1;
-+ audit_log_pid_context(context, axs->target_pid[i],
-+ axs->target_auid[i],
-+ axs->target_uid[i],
-+ axs->target_sessionid[i],
-+ &axs->target_lsm[i],
-+ axs->target_comm[i]);
++ if (final == NULL)
++ return -EINVAL;
++ *value = final;
++ return finallen;
+ }
+
-+ if (context->target_pid)
-+ audit_log_pid_context(context, context->target_pid,
-+ context->target_auid, context->target_uid,
-+ context->target_sessionid,
-+ &context->target_lsm,
-+ context->target_comm);
-
- if (context->pwd.dentry && context->pwd.mnt) {
- ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
+ hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) {
+ if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm))
+ continue;
--
-2.35.1
+2.20.1