From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:41:03
Implement audit kernel container ID.
This patchset is a preliminary RFC based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch implements the proc fs write to set the audit container
ID of a process, emitting an AUDIT_CONTAINER record.
The second implements an auxiliary syscall record AUDIT_CONTAINER_INFO
if a container ID is present on a task.
The third adds filtering to the exit, exclude and user lists.
The 4th, implements reading the container ID from the proc filesystem
for debugging. This isn't planned for upstream inclusion.
The 5th adds signal and ptrace support.
The 6th attempts to create a local audit context to be able to bind a
standalone record with the container ID record.
The 7th, 8th, 9th, 10th patches add container ID records to standalone
records. Some of these may end up being syscall auxiliary records and
won't need this specific support since they'll be supported via
syscalls.
The 11th is a temporary workaround due to the AUDIT_CONTAINER records
not showing up as do AUDIT_LOGIN records. I suspect this is due to its
range (1000 vs 1300), but the intent is to solve it.
The 12th adds debug information not intended for upstream for those
brave souls wanting to tinker with it in this early state.
Feedback please!
Here's a quick and dirty test script:
echo 123455 > /proc/$$/containerid; echo $?
sleep 4&
child=$!; sleep 1
echo 18446744073709551615 > /proc/$child/containerid; echo $?
echo 123456 > /proc/$child/containerid; echo $?
echo 123457 > /proc/$child/containerid; echo $?
sleep 1
ausearch -ts recent |grep " contid=18446744073709551615"; echo $?
ausearch -ts recent |grep " contid=123456"; echo $?
ausearch -ts recent |grep " contid=123457"; echo $?
echo self:$$ contid:$( cat /proc/$$/containerid)
echo child:$child contid:$( cat /proc/$child/containerid)
containerid=123458
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F containerid=$containerid -F key=$key || echo failed to add containerid filter rule
bash -c "sleep 1; echo test > /tmp/$key"&
child=$!
echo $containerid > /proc/$child/containerid
sleep 2
rm -f /tmp/$key
ausearch -ts recent -k $key || echo failed to find CONTAINER_INFO record
auditctl -d exit,always -F dir=/tmp -F perm=wa -F containerid=$containerid -F key=$key || echo failed to add containerid filter rule
See:
https://github.com/linux-audit/audit-kernel/issues/32https://github.com/linux-audit/audit-userspace/issues/40https://github.com/linux-audit/audit-testsuite/issues/64
Richard Guy Briggs (12):
audit: add container id
audit: log container info of syscalls
audit: add containerid filtering
audit: read container ID of a process
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add container aux record to watch/tree/mark
audit: add containerid support for tty_audit
audit: add containerid support for config/feature/user records
audit: add containerid support for seccomp and anom_abend records
debug audit: add container id
debug! audit: add container id
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 63 +++++++++++++++++++
include/linux/audit.h | 36 +++++++++++
include/linux/init_task.h | 4 +-
include/linux/sched.h | 1 +
include/uapi/linux/audit.h | 9 ++-
kernel/audit.c | 74 +++++++++++++++++++---
kernel/audit.h | 3 +
kernel/audit_fsnotify.c | 5 +-
kernel/audit_tree.c | 5 +-
kernel/audit_watch.c | 33 +++++-----
kernel/auditfilter.c | 52 ++++++++++++++-
kernel/auditsc.c | 154 +++++++++++++++++++++++++++++++++++++++++++--
13 files changed, 408 insertions(+), 36 deletions(-)
--
1.8.3.1
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:41:04
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
See: https://github.com/linux-audit/audit-kernel/issues/32
Signed-off-by: Richard Guy Briggs <redacted>
---
fs/proc/base.c | 37 ++++++++++++++++++++
include/linux/audit.h | 16 +++++++++
include/linux/init_task.h | 4 ++-
include/linux/sched.h | 1 +
include/uapi/linux/audit.h | 2 ++
kernel/auditsc.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 145 insertions(+), 1 deletion(-)
@@ -71,6 +71,7 @@#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */#define AUDIT_SET_FEATURE 1018 /* Turn an audit feature on or off */#define AUDIT_GET_FEATURE 1019 /* Get which features are enabled */+#define AUDIT_CONTAINER 1020 /* Define the container id and information */#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */#define AUDIT_USER_AVC 1107 /* We filter this differently */
@@ -465,6 +466,7 @@ struct audit_tty_status {};#define AUDIT_UID_UNSET (unsigned int)-1+#define AUDIT_CID_UNSET ((u64)-1)/* audit_rule_data supports filter rules with both integer and string*fields.ItcorrespondswithAUDIT_ADD_RULE,AUDIT_DEL_RULEand
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;+/* it is already set, and not inherited from the parent, reject */+ccontainerid=audit_get_containerid(task);+rcu_read_lock();+parent=rcu_dereference(task->real_parent);+rcu_read_unlock();+task_lock(parent);+pcontainerid=audit_get_containerid(parent);+ppid=task_tgid_nr(parent);+task_unlock(parent);+if(ccontainerid!=pcontainerid)+return-EPERM;+return0;+}++staticvoidaudit_log_set_containerid(structtask_struct*task,u64oldcontainerid,+u64containerid,intrc)+{+structaudit_buffer*ab;+uid_tuid;+structtty_struct*tty;++if(!audit_enabled)+return;++ab=audit_log_start(NULL,GFP_KERNEL,AUDIT_CONTAINER);+if(!ab)+return;++uid=from_kuid(&init_user_ns,task_uid(current));+tty=audit_get_tty(current);++audit_log_format(ab,"op=set pid=%d uid=%u",task_tgid_nr(current),uid);+audit_log_task_context(ab);+audit_log_format(ab," auid=%u tty=%s ses=%u opid=%d old-contid=%llu contid=%llu res=%d",+from_kuid(&init_user_ns,audit_get_loginuid(current)),+tty?tty_name(tty):"(none)",audit_get_sessionid(current),+task_tgid_nr(task),oldcontainerid,containerid,!rc);++audit_put_tty(tty);+audit_log_end(ab);+}++/**+*audit_set_containerid-setcurrenttask'saudit_contextcontainerid+*@containerid:containeridvalue+*+*Returns0onsuccess,-EPERMonpermissionfailure.+*+*Called(set)fromfs/proc/base.c::proc_containerid_write().+*/+intaudit_set_containerid(structtask_struct*task,u64containerid)+{+u64oldcontainerid;+intrc;++oldcontainerid=audit_get_containerid(task);++rc=audit_set_containerid_perm(task,containerid);+if(!rc){+task_lock(task);+task->containerid=containerid;+task_unlock(task);+}++audit_log_set_containerid(task,oldcontainerid,containerid,rc);+returnrc;+}+/***__audit_mq_open-recordauditdataforaPOSIXMQopen*@oflag:openflag
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:41:06
Implement container ID filtering using the AUDIT_CONTAINERID field name
to send an 8-character string representing a u64 since the value field
is only u32.
Sending it as two u32 was considered, but gathering and comparing two
fields was more complex.
The feature indicator is AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER.
This requires support from userspace to be useful.
See: https://github.com/linux-audit/audit-userspace/issues/40
Signed-off-by: Richard Guy Briggs <redacted>
---
include/linux/audit.h | 1 +
include/uapi/linux/audit.h | 5 ++++-
kernel/audit.h | 1 +
kernel/auditfilter.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
kernel/auditsc.c | 3 +++
5 files changed, 56 insertions(+), 1 deletion(-)
@@ -262,6 +262,7 @@#define AUDIT_LOGINUID_SET 24#define AUDIT_SESSIONID 25 /* Session ID */#define AUDIT_FSTYPE 26 /* FileSystem Type */+#define AUDIT_CONTAINERID 27 /* Container ID *//* These are ONLY useful when checking*atsyscallexittime(AUDIT_AT_EXIT).*/
@@ -410,6 +410,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)/* FALL THROUGH */caseAUDIT_ARCH:caseAUDIT_FSTYPE:+caseAUDIT_CONTAINERID:if(f->op!=Audit_not_equal&&f->op!=Audit_equal)return-EINVAL;break;
@@ -1348,6 +1391,10 @@ int audit_filter(int msgtype, unsigned int listtype)result=audit_comparator(audit_loginuid_set(current),f->op,f->val);break;+caseAUDIT_CONTAINERID:+result=audit_comparator64(audit_get_containerid(current),+f->op,f->val64);+break;caseAUDIT_MSGTYPE:result=audit_comparator(msgtype,f->op,f->val);break;
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:41:08
Add container ID support to ptrace and signals. In particular, the "op"
field provides a way to label the auxiliary record to which it is
associated.
Signed-off-by: Richard Guy Briggs <redacted>
---
include/linux/audit.h | 16 +++++++++++-----
kernel/audit.c | 12 ++++++++----
kernel/audit.h | 2 ++
kernel/auditsc.c | 19 +++++++++++++++----
4 files changed, 36 insertions(+), 13 deletions(-)
@@ -142,6 +142,7 @@ struct audit_net {kuid_taudit_sig_uid=INVALID_UID;pid_taudit_sig_pid=-1;u32audit_sig_sid=0;+u64audit_sig_cid=INVALID_CID;/* Records can be lost in several ways:0)[suppressedinaudit_alloc]
@@ -1456,7 +1463,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *tsaudit_log_proctitle(tsk,context);-audit_log_container_info(tsk,context);+audit_log_container_info(context,"task",audit_get_containerid(tsk));/* Send end of event record to help user space know we are finished */ab=audit_log_start(context,GFP_KERNEL,AUDIT_EOE);
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:41:09
Standalone audit records have the timestamp and serial number generated
on the fly and as such are unique, making them standalone. This is a
prototype of a method to generate a local audit context that will be
used only for a standalone record and its auxiliary record. The context
is discarded immediately after the local associated records are
produced.
Signed-off-by: Richard Guy Briggs <redacted>
---
include/linux/audit.h | 8 ++++++++
kernel/auditsc.c | 20 +++++++++++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
@@ -227,7 +227,9 @@ static inline int audit_log_container_info(struct audit_context *context,/* These are defined in auditsc.c *//* Public API */externintaudit_alloc(structtask_struct*task);+externstructaudit_context*audit_alloc_local(void);externvoid__audit_free(structtask_struct*task);+externvoidaudit_free_context(structaudit_context*context);externvoid__audit_syscall_entry(intmajor,unsignedlonga0,unsignedlonga1,unsignedlonga2,unsignedlonga3);externvoid__audit_syscall_exit(intret_success,longret_value);
@@ -472,6 +474,12 @@ static inline int audit_alloc(struct task_struct *task){return0;}+staticinlinestructaudit_context*audit_alloc_local(void)+{+returnNULL;+}+staticinlinevoidaudit_free_context(structaudit_context*context)+{}staticinlinevoidaudit_free(structtask_struct*task){}staticinlinevoidaudit_syscall_entry(intmajor,unsignedlonga0,
@@ -959,8 +959,26 @@ int audit_alloc(struct task_struct *tsk)return0;}-staticinlinevoidaudit_free_context(structaudit_context*context)+structaudit_context*audit_alloc_local(void){+structaudit_context*context;++if(likely(!audit_ever_enabled))+returnNULL;/* Return if not auditing. */++context=audit_alloc_context(AUDIT_RECORD_CONTEXT);+if(!context)+returnNULL;+context->serial=audit_serial();+context->ctime=current_kernel_time64();+context->in_syscall=1;+returncontext;+}++inlinevoidaudit_free_context(structaudit_context*context)+{+if(!context)+return;audit_free_names(context);unroll_tree_refs(context,NULL,0);free_tree_refs(context);
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:41:11
Add container ID information to tty logging rule standalone records.
Signed-off-by: Richard Guy Briggs <redacted>
---
drivers/tty/tty_audit.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:41:14
Switch from the 1000 range to the 1300 range for the prototype until it
can be worked out why the former aren't showing up in the logs.
---
include/uapi/linux/audit.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
@@ -71,7 +71,8 @@#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */#define AUDIT_SET_FEATURE 1018 /* Turn an audit feature on or off */#define AUDIT_GET_FEATURE 1019 /* Get which features are enabled */-#define AUDIT_CONTAINER 1020 /* Define the container id and information */+//#define AUDIT_CONTAINER 1020 /* Define the container id and information */+#define AUDIT_CONTAINER 1333 /* Define the container id and information */#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */#define AUDIT_USER_AVC 1107 /* We filter this differently */
@@ -2111,16 +2111,28 @@ static int audit_set_containerid_perm(struct task_struct *task, u64 containerid)/* Don't allow to set our own containerid */if(current==task)+{+pr_info("pid=%d can't set own containerid",task_tgid_nr(task));return-EPERM;+}/* Don't allow the containerid to be unset */if(!cid_valid(containerid))+{+pr_info("can't unset containerid");return-EINVAL;+}/* if we don't have caps, reject */if(!capable(CAP_AUDIT_CONTROL))+{+pr_info("don't have CAP_AUDIT_CONTROL");return-EPERM;+}/* if containerid is unset, allow */if(!audit_containerid_set(task))+{+//pr_info("unset, allow");return0;+}/* it is already set, and not inherited from the parent, reject */ccontainerid=audit_get_containerid(task);rcu_read_lock();
@@ -2131,7 +2143,11 @@ static int audit_set_containerid_perm(struct task_struct *task, u64 containerid)ppid=task_tgid_nr(parent);task_unlock(parent);if(ccontainerid!=pcontainerid)+{+pr_info("pid=%d already has contid=%llu set, not inherited from ppid=%d with contid=%llu, can't set containerid %llu",+task_tgid_nr(task),ccontainerid,ppid,pcontainerid,containerid);return-EPERM;+}return0;}
@@ -1453,6 +1453,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *tsaudit_log_proctitle(tsk,context);+audit_log_container_info(tsk,context);+/* Send end of event record to help user space know we are finished */ab=audit_log_start(context,GFP_KERNEL,AUDIT_EOE);if(ab)
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:46:40
Add support for reading the container ID from the proc filesystem.
This is a read from the proc entry of the form /proc/PID/containerid
where PID is the process ID of the task whose container ID is sought.
The read expects up to a u64 value (unset: 18446744073709551615).
Signed-off-by: Richard Guy Briggs <redacted>
---
fs/proc/base.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:46:59
Add container ID information to mark, watch and tree rule standalone
records.
Signed-off-by: Richard Guy Briggs <redacted>
---
kernel/audit_fsnotify.c | 5 ++++-
kernel/audit_tree.c | 5 ++++-
kernel/audit_watch.c | 33 +++++++++++++++++++--------------
3 files changed, 27 insertions(+), 16 deletions(-)
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:47:13
Add container ID information to configuration change, feature set change
and user generated standalone records.
Signed-off-by: Richard Guy Briggs <redacted>
---
kernel/audit.c | 50 ++++++++++++++++++++++++++++++++++++++++----------
kernel/auditfilter.c | 5 ++++-
2 files changed, 44 insertions(+), 11 deletions(-)
@@ -1415,6 +1441,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)structaudit_tty_statuss,old;structaudit_buffer*ab;unsignedintt;+structaudit_context*context=audit_alloc_local();memset(&s,0,sizeof(s));/* guard against past and future API changes */
From: Richard Guy Briggs <hidden> Date: 2018-03-01 19:47:17
Add container ID information to secure computing and abnormal end
standalone records.
Signed-off-by: Richard Guy Briggs <redacted>
---
kernel/auditsc.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
@@ -2576,19 +2577,22 @@ void audit_core_dumps(long signr)if(signr==SIGQUIT)/* don't care for those */return;-ab=audit_log_start(NULL,GFP_KERNEL,AUDIT_ANOM_ABEND);+ab=audit_log_start(context,GFP_KERNEL,AUDIT_ANOM_ABEND);if(unlikely(!ab))return;audit_log_task(ab);audit_log_format(ab," sig=%ld res=1",signr);audit_log_end(ab);+audit_log_container_info(context,"abend",audit_get_containerid(current));+audit_free_context(context);}void__audit_seccomp(unsignedlongsyscall,longsignr,intcode){structaudit_buffer*ab;+structaudit_context*context=audit_alloc_local();-ab=audit_log_start(NULL,GFP_KERNEL,AUDIT_SECCOMP);+ab=audit_log_start(context,GFP_KERNEL,AUDIT_SECCOMP);if(unlikely(!ab))return;audit_log_task(ab);
@@ -2596,6 +2600,8 @@ void __audit_seccomp(unsigned long syscall, long signr, int code)signr,syscall_get_arch(),syscall,in_compat_syscall(),KSTK_EIP(current),code);audit_log_end(ab);+audit_log_container_info(context,"seccomp",audit_get_containerid(current));+audit_free_context(context);}structlist_head*audit_killed_trees(void)
From: Richard Guy Briggs <hidden> Date: 2018-03-02 01:45:24
On 2018-03-01 14:41, Richard Guy Briggs wrote:
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
There are more restrictions coming later:
- check that the child being set has no children or threads yet, or
forcibly set them all to the same container ID (assuming they all pass
the same tests). This will also prevent an orch from setting its
parent and other tit-for-tat games to circumvent the basic checks.
@@ -71,6 +71,7 @@#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */#define AUDIT_SET_FEATURE 1018 /* Turn an audit feature on or off */#define AUDIT_GET_FEATURE 1019 /* Get which features are enabled */+#define AUDIT_CONTAINER 1020 /* Define the container id and information */#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */#define AUDIT_USER_AVC 1107 /* We filter this differently */
@@ -465,6 +466,7 @@ struct audit_tty_status {};#define AUDIT_UID_UNSET (unsigned int)-1+#define AUDIT_CID_UNSET ((u64)-1)/* audit_rule_data supports filter rules with both integer and string*fields.ItcorrespondswithAUDIT_ADD_RULE,AUDIT_DEL_RULEand
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;+/* it is already set, and not inherited from the parent, reject */+ccontainerid=audit_get_containerid(task);+rcu_read_lock();+parent=rcu_dereference(task->real_parent);+rcu_read_unlock();+task_lock(parent);+pcontainerid=audit_get_containerid(parent);+ppid=task_tgid_nr(parent);+task_unlock(parent);+if(ccontainerid!=pcontainerid)+return-EPERM;+return0;+}++staticvoidaudit_log_set_containerid(structtask_struct*task,u64oldcontainerid,+u64containerid,intrc)+{+structaudit_buffer*ab;+uid_tuid;+structtty_struct*tty;++if(!audit_enabled)+return;++ab=audit_log_start(NULL,GFP_KERNEL,AUDIT_CONTAINER);+if(!ab)+return;++uid=from_kuid(&init_user_ns,task_uid(current));+tty=audit_get_tty(current);++audit_log_format(ab,"op=set pid=%d uid=%u",task_tgid_nr(current),uid);+audit_log_task_context(ab);+audit_log_format(ab," auid=%u tty=%s ses=%u opid=%d old-contid=%llu contid=%llu res=%d",+from_kuid(&init_user_ns,audit_get_loginuid(current)),+tty?tty_name(tty):"(none)",audit_get_sessionid(current),+task_tgid_nr(task),oldcontainerid,containerid,!rc);++audit_put_tty(tty);+audit_log_end(ab);+}++/**+*audit_set_containerid-setcurrenttask'saudit_contextcontainerid+*@containerid:containeridvalue+*+*Returns0onsuccess,-EPERMonpermissionfailure.+*+*Called(set)fromfs/proc/base.c::proc_containerid_write().+*/+intaudit_set_containerid(structtask_struct*task,u64containerid)+{+u64oldcontainerid;+intrc;++oldcontainerid=audit_get_containerid(task);++rc=audit_set_containerid_perm(task,containerid);+if(!rc){+task_lock(task);+task->containerid=containerid;+task_unlock(task);+}++audit_log_set_containerid(task,oldcontainerid,containerid,rc);+returnrc;+}+/***__audit_mq_open-recordauditdataforaPOSIXMQopen*@oflag:openflag
--
1.8.3.1
- RGB
--
Richard Guy Briggs [off-list ref]
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
From: Paul Moore <paul@paul-moore.com> Date: 2018-03-02 15:48:42
On Thu, Mar 1, 2018 at 8:41 PM, Richard Guy Briggs [off-list ref] wrote:
On 2018-03-01 14:41, Richard Guy Briggs wrote:
quoted
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
There are more restrictions coming later:
- check that the child being set has no children or threads yet, or
forcibly set them all to the same container ID (assuming they all pass
the same tests). This will also prevent an orch from setting its
parent and other tit-for-tat games to circumvent the basic checks.
FYI, I think you may have a problem with something in your outgoing
mail path; I didn't receive the original patchset you are referencing
and it doesn't appear in the mail archive either.
--
paul moore
www.paul-moore.com
From: Matthew Wilcox <willy@infradead.org> Date: 2018-03-02 18:23:25
On Fri, Mar 02, 2018 at 10:48:42AM -0500, Paul Moore wrote:
On Thu, Mar 1, 2018 at 8:41 PM, Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-03-01 14:41, Richard Guy Briggs wrote:
FYI, I think you may have a problem with something in your outgoing
mail path; I didn't receive the original patchset you are referencing
and it doesn't appear in the mail archive either.
I have those patches. Which mail archive is missing them?
From: Paul Moore <paul@paul-moore.com> Date: 2018-03-02 19:26:00
On Fri, Mar 2, 2018 at 1:23 PM, Matthew Wilcox [off-list ref] wrote:
On Fri, Mar 02, 2018 at 10:48:42AM -0500, Paul Moore wrote:
quoted
On Thu, Mar 1, 2018 at 8:41 PM, Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-03-01 14:41, Richard Guy Briggs wrote:
FYI, I think you may have a problem with something in your outgoing
mail path; I didn't receive the original patchset you are referencing
and it doesn't appear in the mail archive either.
I have those patches. Which mail archive is missing them?
Hi Richard,
the calls to audit_containerid_set() confused me. Could you make it
is_audit_containerid_set() or audit_containerid_isset()?
I haven't gone through the entire patchset yet, but I wanted to
quickly comment on this ... I really dislike the
function-names-as-sentences approach and would would greatly prefer
audit_containerid_isset().
On Thu, 2018-03-01 at 14:41 -0500, Richard Guy Briggs wrote:
Implement audit kernel container ID.
This patchset is a preliminary RFC based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch implements the proc fs write to set the audit container
ID of a process, emitting an AUDIT_CONTAINER record.
The second implements an auxiliary syscall record AUDIT_CONTAINER_INFO
if a container ID is present on a task.
The third adds filtering to the exit, exclude and user lists.
The 4th, implements reading the container ID from the proc filesystem
for debugging. This isn't planned for upstream inclusion.
The 5th adds signal and ptrace support.
The 6th attempts to create a local audit context to be able to bind a
standalone record with the container ID record.
The 7th, 8th, 9th, 10th patches add container ID records to standalone
records. Some of these may end up being syscall auxiliary records and
won't need this specific support since they'll be supported via
syscalls.
The 11th is a temporary workaround due to the AUDIT_CONTAINER records
not showing up as do AUDIT_LOGIN records. I suspect this is due to its
range (1000 vs 1300), but the intent is to solve it.
The 12th adds debug information not intended for upstream for those
brave souls wanting to tinker with it in this early state.
Feedback please!
Which tree can this patch set be applied to?
Mimi
Here's a quick and dirty test script:
echo 123455 > /proc/$$/containerid; echo $?
sleep 4&
child=$!; sleep 1
echo 18446744073709551615 > /proc/$child/containerid; echo $?
echo 123456 > /proc/$child/containerid; echo $?
echo 123457 > /proc/$child/containerid; echo $?
sleep 1
ausearch -ts recent |grep " contid=18446744073709551615"; echo $?
ausearch -ts recent |grep " contid=123456"; echo $?
ausearch -ts recent |grep " contid=123457"; echo $?
echo self:$$ contid:$( cat /proc/$$/containerid)
echo child:$child contid:$( cat /proc/$child/containerid)
containerid=123458
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F containerid=$containerid -F key=$key || echo failed to add containerid filter rule
bash -c "sleep 1; echo test > /tmp/$key"&
child=$!
echo $containerid > /proc/$child/containerid
sleep 2
rm -f /tmp/$key
ausearch -ts recent -k $key || echo failed to find CONTAINER_INFO record
auditctl -d exit,always -F dir=/tmp -F perm=wa -F containerid=$containerid -F key=$key || echo failed to add containerid filter rule
See:
https://github.com/linux-audit/audit-kernel/issues/32https://github.com/linux-audit/audit-userspace/issues/40https://github.com/linux-audit/audit-testsuite/issues/64
Richard Guy Briggs (12):
audit: add container id
audit: log container info of syscalls
audit: add containerid filtering
audit: read container ID of a process
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add container aux record to watch/tree/mark
audit: add containerid support for tty_audit
audit: add containerid support for config/feature/user records
audit: add containerid support for seccomp and anom_abend records
debug audit: add container id
debug! audit: add container id
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 63 +++++++++++++++++++
include/linux/audit.h | 36 +++++++++++
include/linux/init_task.h | 4 +-
include/linux/sched.h | 1 +
include/uapi/linux/audit.h | 9 ++-
kernel/audit.c | 74 +++++++++++++++++++---
kernel/audit.h | 3 +
kernel/audit_fsnotify.c | 5 +-
kernel/audit_tree.c | 5 +-
kernel/audit_watch.c | 33 +++++-----
kernel/auditfilter.c | 52 ++++++++++++++-
kernel/auditsc.c | 154 +++++++++++++++++++++++++++++++++++++++++++--
13 files changed, 408 insertions(+), 36 deletions(-)
From: Richard Guy Briggs <hidden> Date: 2018-03-05 03:36:06
On 2018-03-04 16:55, Mimi Zohar wrote:
On Thu, 2018-03-01 at 14:41 -0500, Richard Guy Briggs wrote:
quoted
Implement audit kernel container ID.
This patchset is a preliminary RFC based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch implements the proc fs write to set the audit container
ID of a process, emitting an AUDIT_CONTAINER record.
The second implements an auxiliary syscall record AUDIT_CONTAINER_INFO
if a container ID is present on a task.
The third adds filtering to the exit, exclude and user lists.
The 4th, implements reading the container ID from the proc filesystem
for debugging. This isn't planned for upstream inclusion.
The 5th adds signal and ptrace support.
The 6th attempts to create a local audit context to be able to bind a
standalone record with the container ID record.
The 7th, 8th, 9th, 10th patches add container ID records to standalone
records. Some of these may end up being syscall auxiliary records and
won't need this specific support since they'll be supported via
syscalls.
The 11th is a temporary workaround due to the AUDIT_CONTAINER records
not showing up as do AUDIT_LOGIN records. I suspect this is due to its
range (1000 vs 1300), but the intent is to solve it.
The 12th adds debug information not intended for upstream for those
brave souls wanting to tinker with it in this early state.
Feedback please!
Which tree can this patch set be applied to?
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git next
Mimi
quoted
Here's a quick and dirty test script:
echo 123455 > /proc/$$/containerid; echo $?
sleep 4&
child=$!; sleep 1
echo 18446744073709551615 > /proc/$child/containerid; echo $?
echo 123456 > /proc/$child/containerid; echo $?
echo 123457 > /proc/$child/containerid; echo $?
sleep 1
ausearch -ts recent |grep " contid=18446744073709551615"; echo $?
ausearch -ts recent |grep " contid=123456"; echo $?
ausearch -ts recent |grep " contid=123457"; echo $?
echo self:$$ contid:$( cat /proc/$$/containerid)
echo child:$child contid:$( cat /proc/$child/containerid)
containerid=123458
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F containerid=$containerid -F key=$key || echo failed to add containerid filter rule
bash -c "sleep 1; echo test > /tmp/$key"&
child=$!
echo $containerid > /proc/$child/containerid
sleep 2
rm -f /tmp/$key
ausearch -ts recent -k $key || echo failed to find CONTAINER_INFO record
auditctl -d exit,always -F dir=/tmp -F perm=wa -F containerid=$containerid -F key=$key || echo failed to add containerid filter rule
See:
https://github.com/linux-audit/audit-kernel/issues/32https://github.com/linux-audit/audit-userspace/issues/40https://github.com/linux-audit/audit-testsuite/issues/64
Richard Guy Briggs (12):
audit: add container id
audit: log container info of syscalls
audit: add containerid filtering
audit: read container ID of a process
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add container aux record to watch/tree/mark
audit: add containerid support for tty_audit
audit: add containerid support for config/feature/user records
audit: add containerid support for seccomp and anom_abend records
debug audit: add container id
debug! audit: add container id
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 63 +++++++++++++++++++
include/linux/audit.h | 36 +++++++++++
include/linux/init_task.h | 4 +-
include/linux/sched.h | 1 +
include/uapi/linux/audit.h | 9 ++-
kernel/audit.c | 74 +++++++++++++++++++---
kernel/audit.h | 3 +
kernel/audit_fsnotify.c | 5 +-
kernel/audit_tree.c | 5 +-
kernel/audit_watch.c | 33 +++++-----
kernel/auditfilter.c | 52 ++++++++++++++-
kernel/auditsc.c | 154 +++++++++++++++++++++++++++++++++++++++++++--
13 files changed, 408 insertions(+), 36 deletions(-)
- RGB
--
Richard Guy Briggs [off-list ref]
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
Hi Richard,
the calls to audit_containerid_set() confused me. Could you make it
is_audit_containerid_set() or audit_containerid_isset()?
I haven't gone through the entire patchset yet, but I wanted to
quickly comment on this ... I really dislike the
function-names-as-sentences approach and would would greatly prefer
audit_containerid_isset().
I'd be ok with this latter if necessary, but the naming mimics the
existing loginuid naming convention.
- RGB
--
Richard Guy Briggs [off-list ref]
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
On Sun, 2018-03-04 at 22:31 -0500, Richard Guy Briggs wrote:
On 2018-03-04 16:55, Mimi Zohar wrote:
quoted
On Thu, 2018-03-01 at 14:41 -0500, Richard Guy Briggs wrote:
quoted
Implement audit kernel container ID.
This patchset is a preliminary RFC based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch implements the proc fs write to set the audit container
ID of a process, emitting an AUDIT_CONTAINER record.
The second implements an auxiliary syscall record AUDIT_CONTAINER_INFO
if a container ID is present on a task.
The third adds filtering to the exit, exclude and user lists.
The 4th, implements reading the container ID from the proc filesystem
for debugging. This isn't planned for upstream inclusion.
The 5th adds signal and ptrace support.
The 6th attempts to create a local audit context to be able to bind a
standalone record with the container ID record.
The 7th, 8th, 9th, 10th patches add container ID records to standalone
records. Some of these may end up being syscall auxiliary records and
won't need this specific support since they'll be supported via
syscalls.
The 11th is a temporary workaround due to the AUDIT_CONTAINER records
not showing up as do AUDIT_LOGIN records. I suspect this is due to its
range (1000 vs 1300), but the intent is to solve it.
The 12th adds debug information not intended for upstream for those
brave souls wanting to tinker with it in this early state.
Feedback please!
Which tree can this patch set be applied to?
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git next
Thanks, that worked. In case anyone else is trying to apply these
patches to a 4.16.0-rc based kernel, commit 4e7e3adbba52 ("Expand
various INIT_* macros and remove") moved .sessionid
to init/init_task.c.
Mimi
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
From: Stefan Berger <hidden> Date: 2018-03-15 20:27:01
On 03/01/2018 02:41 PM, Richard Guy Briggs wrote:
quoted hunk
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
See: https://github.com/linux-audit/audit-kernel/issues/32
/* audit_rule_data supports filter rules with both integer and string
* fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;
I am wondering whether there should be a check for the target process
that will receive the containerid to not have CAP_SYS_ADMIN that would
otherwise allow it to arbitrarily unshare()/clone() and leave the set of
namespaces that may make up the container whose containerid we assign here?
+ /* it is already set, and not inherited from the parent, reject */
+ ccontainerid = audit_get_containerid(task);
+ rcu_read_lock();
+ parent = rcu_dereference(task->real_parent);
+ rcu_read_unlock();
+ task_lock(parent);
+ pcontainerid = audit_get_containerid(parent);
+ ppid = task_tgid_nr(parent);
From: Richard Guy Briggs <hidden> Date: 2018-03-16 03:58:37
On 2018-03-15 16:27, Stefan Berger wrote:
On 03/01/2018 02:41 PM, Richard Guy Briggs wrote:
quoted
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
See: https://github.com/linux-audit/audit-kernel/issues/32
/* audit_rule_data supports filter rules with both integer and string
* fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;
I am wondering whether there should be a check for the target process that
will receive the containerid to not have CAP_SYS_ADMIN that would otherwise
allow it to arbitrarily unshare()/clone() and leave the set of namespaces
that may make up the container whose containerid we assign here?
This is a reasonable question. This has been debated and I understood
the conclusion was that without a clear definition of a "container", the
task still remains in that container that just now has more
sub-namespaces (in the case of hierarchical namespaces), we don't want
to restrict it in such a way and that allows it to create nested
containers. I see setns being more problematic if it could switch to
another existing namespace that was set up by the orchestrator for a
different container. The coming v2 patchset acknowledges this situation
with the network namespace being potentially shared by multiple
containers.
This is the motivation for the code below that allows to set the
containerid even if it is already inherited from its parent.
quoted
+ /* it is already set, and not inherited from the parent, reject */
+ ccontainerid = audit_get_containerid(task);
+ rcu_read_lock();
+ parent = rcu_dereference(task->real_parent);
+ rcu_read_unlock();
+ task_lock(parent);
+ pcontainerid = audit_get_containerid(parent);
+ ppid = task_tgid_nr(parent);
ppid not needed...
Thanks for catching this. It was the vestige of a failed devel
experiment that didn't flush that useless appendage. :-)
- RGB
--
Richard Guy Briggs [off-list ref]
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
From: Stefan Berger <hidden> Date: 2018-04-18 18:45:14
On 03/15/2018 11:58 PM, Richard Guy Briggs wrote:
On 2018-03-15 16:27, Stefan Berger wrote:
quoted
On 03/01/2018 02:41 PM, Richard Guy Briggs wrote:
quoted
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
See: https://github.com/linux-audit/audit-kernel/issues/32
/* audit_rule_data supports filter rules with both integer and string
* fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;
I am wondering whether there should be a check for the target process that
will receive the containerid to not have CAP_SYS_ADMIN that would otherwise
allow it to arbitrarily unshare()/clone() and leave the set of namespaces
that may make up the container whose containerid we assign here?
This is a reasonable question. This has been debated and I understood
the conclusion was that without a clear definition of a "container", the
task still remains in that container that just now has more
sub-namespaces (in the case of hierarchical namespaces), we don't want
to restrict it in such a way and that allows it to create nested
containers. I see setns being more problematic if it could switch to
another existing namespace that was set up by the orchestrator for a
different container. The coming v2 patchset acknowledges this situation
with the network namespace being potentially shared by multiple
containers.
Are you going to post v2 soon? We would like to build on top of it for
IMA namespacing and auditing inside of IMA namespaces.
Stefan
From: Richard Guy Briggs <hidden> Date: 2018-04-18 19:29:56
On 2018-04-18 14:45, Stefan Berger wrote:
On 03/15/2018 11:58 PM, Richard Guy Briggs wrote:
quoted
On 2018-03-15 16:27, Stefan Berger wrote:
quoted
On 03/01/2018 02:41 PM, Richard Guy Briggs wrote:
quoted
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
See: https://github.com/linux-audit/audit-kernel/issues/32
/* audit_rule_data supports filter rules with both integer and string
* fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;
I am wondering whether there should be a check for the target process that
will receive the containerid to not have CAP_SYS_ADMIN that would otherwise
allow it to arbitrarily unshare()/clone() and leave the set of namespaces
that may make up the container whose containerid we assign here?
This is a reasonable question. This has been debated and I understood
the conclusion was that without a clear definition of a "container", the
task still remains in that container that just now has more
sub-namespaces (in the case of hierarchical namespaces), we don't want
to restrict it in such a way and that allows it to create nested
containers. I see setns being more problematic if it could switch to
another existing namespace that was set up by the orchestrator for a
different container. The coming v2 patchset acknowledges this situation
with the network namespace being potentially shared by multiple
containers.
Are you going to post v2 soon? We would like to build on top of it for IMA
namespacing and auditing inside of IMA namespaces.
- RGB
--
Richard Guy Briggs [off-list ref]
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
From: Stefan Berger <hidden> Date: 2018-04-18 19:39:29
On 04/18/2018 03:23 PM, Richard Guy Briggs wrote:
On 2018-04-18 14:45, Stefan Berger wrote:
quoted
On 03/15/2018 11:58 PM, Richard Guy Briggs wrote:
quoted
On 2018-03-15 16:27, Stefan Berger wrote:
quoted
On 03/01/2018 02:41 PM, Richard Guy Briggs wrote:
quoted
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
See: https://github.com/linux-audit/audit-kernel/issues/32
/* audit_rule_data supports filter rules with both integer and string
* fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;
I am wondering whether there should be a check for the target process that
will receive the containerid to not have CAP_SYS_ADMIN that would otherwise
allow it to arbitrarily unshare()/clone() and leave the set of namespaces
that may make up the container whose containerid we assign here?
This is a reasonable question. This has been debated and I understood
the conclusion was that without a clear definition of a "container", the
task still remains in that container that just now has more
sub-namespaces (in the case of hierarchical namespaces), we don't want
to restrict it in such a way and that allows it to create nested
containers. I see setns being more problematic if it could switch to
another existing namespace that was set up by the orchestrator for a
different container. The coming v2 patchset acknowledges this situation
with the network namespace being potentially shared by multiple
containers.
Are you going to post v2 soon? We would like to build on top of it for IMA
namespacing and auditing inside of IMA namespaces.
Thanks. I hadn't actually looked at primarily due to the ghak and ghau
in the title. Whatever these may mean.
Does V2 or will V3 prevent a privileged process to setns() to a whole
different set of namespaces and still be audited with that initial
container id ?
From: Richard Guy Briggs <hidden> Date: 2018-04-18 19:57:40
On 2018-04-18 15:39, Stefan Berger wrote:
On 04/18/2018 03:23 PM, Richard Guy Briggs wrote:
quoted
On 2018-04-18 14:45, Stefan Berger wrote:
quoted
On 03/15/2018 11:58 PM, Richard Guy Briggs wrote:
quoted
On 2018-03-15 16:27, Stefan Berger wrote:
quoted
On 03/01/2018 02:41 PM, Richard Guy Briggs wrote:
quoted
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.
This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/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).
This will produce a record such as this:
type=UNKNOWN[1333] msg=audit(1519903238.968:261): op=set pid=596 uid=0 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0
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 container ID values are given in the
"contid" fields, while res indicates its success.
It is not permitted to self-set, unset or re-set the container ID. A
child inherits its parent's container ID, but then can be set only once
after.
See: https://github.com/linux-audit/audit-kernel/issues/32
/* audit_rule_data supports filter rules with both integer and string
* fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
@@ -2073,6 +2073,92 @@ int audit_set_loginuid(kuid_t loginuid)returnrc;}+staticintaudit_set_containerid_perm(structtask_struct*task,u64containerid)+{+structtask_struct*parent;+u64pcontainerid,ccontainerid;+pid_tppid;++/* Don't allow to set our own containerid */+if(current==task)+return-EPERM;+/* Don't allow the containerid to be unset */+if(!cid_valid(containerid))+return-EINVAL;+/* if we don't have caps, reject */+if(!capable(CAP_AUDIT_CONTROL))+return-EPERM;+/* if containerid is unset, allow */+if(!audit_containerid_set(task))+return0;
I am wondering whether there should be a check for the target process that
will receive the containerid to not have CAP_SYS_ADMIN that would otherwise
allow it to arbitrarily unshare()/clone() and leave the set of namespaces
that may make up the container whose containerid we assign here?
This is a reasonable question. This has been debated and I understood
the conclusion was that without a clear definition of a "container", the
task still remains in that container that just now has more
sub-namespaces (in the case of hierarchical namespaces), we don't want
to restrict it in such a way and that allows it to create nested
containers. I see setns being more problematic if it could switch to
another existing namespace that was set up by the orchestrator for a
different container. The coming v2 patchset acknowledges this situation
with the network namespace being potentially shared by multiple
containers.
Are you going to post v2 soon? We would like to build on top of it for IMA
namespacing and auditing inside of IMA namespaces.
Does V2 or will V3 prevent a privileged process to setns() to a whole
different set of namespaces and still be audited with that initial container
id ?
No, not significantly different from V1 in that respect.
It does not prevent setns(), but will maintain its containerid.
It will prevent games by blocking a child and parent from setting each
other's containerids.
It does check that the task being conainered does not yet have any
children or peer threads.
- RGB
--
Richard Guy Briggs [off-list ref]
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635