Thread (51 messages) 51 messages, 5 authors, 2019-01-24

Re: [PATCH ghak90 (was ghak32) V4 02/10] audit: add container id

From: Paul Moore <paul@paul-moore.com>
Date: 2018-10-20 03:48:32
Also in: linux-fsdevel, lkml, netdev, netfilter-devel

Ooops, I hit send prematurely on this :/  My comments below should
stand, but for things like this I usually try to get through the
entire patchset before sending my comments as later patches can affect
my comments on the earlier patches.

On Fri, Oct 19, 2018 at 3:38 PM Paul Moore [off-list ref] wrote:
On Tue, Jul 31, 2018 at 4:11 PM Richard Guy Briggs [off-list ref] wrote:
quoted
Implement the proc fs write to set the audit container identifier of a
process, emitting an AUDIT_CONTAINER_OP record to document the event.

This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/audit_containerid where PID is the process ID of the
newly created task that is to become the first task in a container, or
an additional task added to a container.

The write expects up to a u64 value (unset: 18446744073709551615).

The writer must have capability CAP_AUDIT_CONTROL.

This will produce a record such as this:
  type=CONTAINER_ID msg=audit(2018-06-06 12:39:29.636:26949) : op=set opid=2209 old-contid=18446744073709551615 contid=123456 pid=628 auid=root uid=root tty=ttyS0 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 comm=bash exe=/usr/bin/bash res=yes
You need to update the record type in the example above.
quoted
The "op" field indicates an initial set.  The "pid" to "ses" fields are
the orchestrator while the "opid" field is the object's PID, the process
being "contained".  Old and new audit container identifier values are
given in the "contid" fields, while res indicates its success.
I understand Steve's concern around the "op" field, but I think it
might be a bit premature to think we might not need to do some sort of
audit container ID management in the future that would want to make
use of the CONTAINER_OP message type.  I would like to see the "op"
field preserved.
quoted
It is not permitted to unset the audit container identifier.
A child inherits its parent's audit container identifier.

See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-userspace/issues/51
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID

Signed-off-by: Richard Guy Briggs <redacted>
Acked-by: Serge Hallyn <serge@hallyn.com>
Acked-by: Steve Grubb <redacted>
---
 fs/proc/base.c             | 37 +++++++++++++++++++++++++
 include/linux/audit.h      | 24 ++++++++++++++++
 include/uapi/linux/audit.h |  2 ++
 kernel/auditsc.c           | 68 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 131 insertions(+)
...
quoted
@@ -2112,6 +2114,72 @@ int audit_set_loginuid(kuid_t loginuid)
 }

 /**
+ * audit_set_contid - set current task's audit_context contid
+ * @contid: contid value
+ *
+ * Returns 0 on success, -EPERM on permission failure.
+ *
+ * Called (set) from fs/proc/base.c::proc_contid_write().
+ */
+int audit_set_contid(struct task_struct *task, u64 contid)
+{
+       u64 oldcontid;
+       int rc = 0;
+       struct audit_buffer *ab;
+       uid_t uid;
+       struct tty_struct *tty;
+       char comm[sizeof(current->comm)];
+
+       task_lock(task);
+       /* Can't set if audit disabled */
+       if (!task->audit) {
+               task_unlock(task);
+               return -ENOPROTOOPT;
+       }
+       oldcontid = audit_get_contid(task);
+       read_lock(&tasklist_lock);
I assume lockdep was happy with nesting the tasklist_lock inside the task lock?
quoted
+       /* Don't allow the audit containerid to be unset */
+       if (!audit_contid_valid(contid))
+               rc = -EINVAL;
+       /* if we don't have caps, reject */
+       else if (!capable(CAP_AUDIT_CONTROL))
+               rc = -EPERM;
+       /* if task has children or is not single-threaded, deny */
+       else if (!list_empty(&task->children))
+               rc = -EBUSY;
+       else if (!(thread_group_leader(task) && thread_group_empty(task)))
+               rc = -EALREADY;
+       read_unlock(&tasklist_lock);
+       if (!rc)
+               task->audit->contid = contid;
+       task_unlock(task);
+
+       if (!audit_enabled)
+               return rc;
+
+       ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONTAINER_OP);
+       if (!ab)
+               return rc;
+
+       uid = from_kuid(&init_user_ns, task_uid(current));
+       tty = audit_get_tty(current);
+       audit_log_format(ab, "op=set opid=%d old-contid=%llu contid=%llu pid=%d uid=%u auid=%u tty=%s ses=%u",
+                        task_tgid_nr(task), oldcontid, contid,
+                        task_tgid_nr(current), uid,
+                        from_kuid(&init_user_ns, audit_get_loginuid(current)),
+                        tty ? tty_name(tty) : "(none)",
+                        audit_get_sessionid(current));
+       audit_put_tty(tty);
+       audit_log_task_context(ab);
+       audit_log_format(ab, " comm=");
+       audit_log_untrustedstring(ab, get_task_comm(comm, current));
+       audit_log_d_path_exe(ab, current->mm);
+       audit_log_format(ab, " res=%d", !rc);
+       audit_log_end(ab);
+       return rc;
+}
--
paul moore
www.paul-moore.com


-- 
paul moore
www.paul-moore.com
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help