From: Richard Guy Briggs <hidden> Date: 2018-07-31 21:53:19
Implement kernel audit container identifier.
This patchset is a fourth based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch is the last patch from ghak81 that is included here as a
convenience.
The second patch implements the proc fs write to set the audit container
identifier of a process, emitting an AUDIT_CONTAINER_OP record to announce the
registration of that audit container identifier on that process. This patch
requires userspace support for record acceptance and proper type
display.
The third implements the auxiliary record AUDIT_CONTAINER if an
audit container identifier is identifiable with an event. This patch
requires userspace support for proper type display.
The 4th adds signal and ptrace support.
The 5th creates a local audit context to be able to bind a standalone
record with a locally created auxiliary record.
The 6th patch adds audit container identifier records to the tty
standalone record.
The 7th adds audit container identifier filtering to the exit,
exclude and user lists. This patch adds the AUDIT_CONTID field and
requires auditctl userspace support for the --contid option.
The 8th adds network namespace audit container identifier labelling
based on member tasks' audit container identifier labels.
The 9th adds audit container identifier support to standalone netfilter
records that don't have a task context and lists each container to which
that net namespace belongs.
The 10th implements reading the audit container identifier from the proc
filesystem for debugging. This patch isn't planned for upstream
inclusion.
Example: Set an audit container identifier of 123456 to the "sleep" task:
sleep 2&
child=$!
echo 123456 > /proc/$child/audit_containerid; echo $?
ausearch -ts recent -m container
echo child:$child contid:$( cat /proc/$child/audit_containerid)
This should produce a record such as:
type=CONTAINER_OP 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
Example: Set a filter on an audit container identifier 123459 on /tmp/tmpcontainerid:
contid=123459
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
perl -e "sleep 1; open(my \$tmpfile, '>', \"/tmp/$key\"); close(\$tmpfile);" &
child=$!
echo $contid > /proc/$child/audit_containerid
sleep 2
ausearch -i -ts recent -k $key
auditctl -d exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
rm -f /tmp/$key
This should produce an event such as:
type=CONTAINER msg=audit(2018-06-06 12:46:31.707:26953) : op=task contid=123459
type=PROCTITLE msg=audit(2018-06-06 12:46:31.707:26953) : proctitle=perl -e sleep 1; open(my $tmpfile, '>', "/tmp/tmpcontainerid"); close($tmpfile);
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=1 name=/tmp/tmpcontainerid inode=25656 dev=00:26 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=0 name=/tmp/ inode=8985 dev=00:26 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=CWD msg=audit(2018-06-06 12:46:31.707:26953) : cwd=/root
type=SYSCALL msg=audit(2018-06-06 12:46:31.707:26953) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffffffffffff9c a1=0x5621f2b81900 a2=O_WRONLY|O_CREAT|O_TRUNC a3=0x1b6 items=2 ppid=628 pid=2232 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=ttyS0 ses=1 comm=perl exe=/usr/bin/perl subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=tmpcontainerid
Includes: https://github.com/linux-audit/audit-kernel/issues/81
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Changelog:
v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(&tasklist_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless
v3
- switched from containerid in task_struct to audit_task_info (depends on ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name collision
v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid
Richard Guy Briggs (10):
audit: collect audit task parameters
audit: add container id
audit: log container info of syscalls
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add containerid support for tty_audit
audit: add containerid filtering
audit: add support for containerid to network namespaces
audit: NETFILTER_PKT: record each container ID associated with a netNS
debug audit: read container ID of a process
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 56 ++++++++++++++
include/linux/audit.h | 95 ++++++++++++++++++++---
include/linux/sched.h | 5 +-
include/uapi/linux/audit.h | 8 +-
init/init_task.c | 3 +-
init/main.c | 2 +
kernel/audit.c | 137 +++++++++++++++++++++++++++++++++
kernel/audit.h | 4 +
kernel/auditfilter.c | 47 ++++++++++++
kernel/auditsc.c | 183 ++++++++++++++++++++++++++++++++++++++++-----
kernel/fork.c | 4 +-
kernel/nsproxy.c | 4 +
net/netfilter/xt_AUDIT.c | 12 ++-
14 files changed, 526 insertions(+), 39 deletions(-)
--
1.8.3.1
From: Richard Guy Briggs <hidden> Date: 2018-07-31 20:07:36
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API.
Collect the existing loginuid, sessionid and audit_context together in a
new struct audit_task_info called "audit" in struct task_struct.
Use kmem_cache to manage this pool of memory.
Un-inline audit_free() to be able to always recover that memory.
See: https://github.com/linux-audit/audit-kernel/issues/81
Signed-off-by: Richard Guy Briggs <redacted>
---
include/linux/audit.h | 34 ++++++++++++++++++++++++----------
include/linux/sched.h | 5 +----
init/init_task.c | 3 +--
init/main.c | 2 ++
kernel/auditsc.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
kernel/fork.c | 4 +++-
6 files changed, 73 insertions(+), 26 deletions(-)
@@ -219,8 +219,15 @@ static inline void audit_log_task_info(struct audit_buffer *ab,/* These are defined in auditsc.c *//* Public API */+structaudit_task_info{+kuid_tloginuid;+unsignedintsessionid;+structaudit_context*ctx;+};+externstructaudit_task_infoinit_struct_audit;+externvoid__initaudit_task_init(void);externintaudit_alloc(structtask_struct*task);-externvoid__audit_free(structtask_struct*task);+externvoidaudit_free(structtask_struct*task);externvoid__audit_syscall_entry(intmajor,unsignedlonga0,unsignedlonga1,unsignedlonga2,unsignedlonga3);externvoid__audit_syscall_exit(intret_success,longret_value);
@@ -940,17 +949,28 @@ int audit_alloc(struct task_struct *tsk)structaudit_context*context;enumaudit_statestate;char*key=NULL;+structaudit_task_info*info;++info=kmem_cache_zalloc(audit_task_cache,GFP_KERNEL);+if(!info)+return-ENOMEM;+info->loginuid=audit_get_loginuid(current);+info->sessionid=audit_get_sessionid(current);+tsk->audit=info;if(likely(!audit_ever_enabled))return0;/* Return if not auditing. */state=audit_filter_task(tsk,&key);if(state==AUDIT_DISABLED){+audit_set_context(tsk,NULL);clear_tsk_thread_flag(tsk,TIF_SYSCALL_AUDIT);return0;}if(!(context=audit_alloc_context(state))){+tsk->audit=NULL;+kmem_cache_free(audit_task_cache,info);kfree(key);audit_log_lost("out of memory in audit_alloc");return-ENOMEM;
@@ -962,6 +982,12 @@ int audit_alloc(struct task_struct *tsk)return0;}+structaudit_task_infoinit_struct_audit={+.loginuid=INVALID_UID,+.sessionid=AUDIT_SID_UNSET,+.ctx=NULL,+};+staticinlinevoidaudit_free_context(structaudit_context*context){audit_free_names(context);
@@ -1469,26 +1495,33 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts}/**-*__audit_free-freeaper-taskauditcontext+*audit_free-freeaper-taskauditcontext*@tsk:taskwhoseauditcontextblocktofree**Calledfromcopy_processanddo_exit*/-void__audit_free(structtask_struct*tsk)+voidaudit_free(structtask_struct*tsk){structaudit_context*context;+structaudit_task_info*info;context=audit_take_context(tsk,0,0);-if(!context)-return;-/* Check for system calls that do not go through the exit*function(e.g.,exit_group),thenfreecontextblock.*WeuseGFP_ATOMICherebecausewemightbedoingthis*inthecontextoftheidlethread*//* that can happen only if we are called from do_exit() */-if(context->in_syscall&&context->current_state==AUDIT_RECORD_CONTEXT)+if(context&&context->in_syscall&&+context->current_state==AUDIT_RECORD_CONTEXT)audit_log_exit(context,tsk);+/* Freeing the audit_task_info struct must be performed after+*audit_log_exit()duetoneedforloginuidandsessionid.+*/+info=tsk->audit;+tsk->audit=NULL;+kmem_cache_free(audit_task_cache,info);+if(!context)+return;if(!list_empty(&context->killed_trees))audit_kill_trees(&context->killed_trees);
@@ -2071,8 +2104,8 @@ int audit_set_loginuid(kuid_t loginuid)sessionid=(unsignedint)atomic_inc_return(&session_id);}-task->sessionid=sessionid;-task->loginuid=loginuid;+task->audit->sessionid=sessionid;+task->audit->loginuid=loginuid;out:audit_log_set_loginuid(oldloginuid,loginuid,oldsessionid,sessionid,rc);returnrc;
From: Richard Guy Briggs <hidden> Date: 2018-07-31 20:07:37
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
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.
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(+)
@@ -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_OP 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 */
@@ -468,6 +469,7 @@ struct audit_tty_status {#define AUDIT_UID_UNSET (unsigned int)-1#define AUDIT_SID_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
@@ -956,6 +956,7 @@ int audit_alloc(struct task_struct *tsk)return-ENOMEM;info->loginuid=audit_get_loginuid(current);info->sessionid=audit_get_sessionid(current);+info->contid=audit_get_contid(current);tsk->audit=info;if(likely(!audit_ever_enabled))
@@ -985,6 +986,7 @@ int audit_alloc(struct task_struct *tsk)structaudit_task_infoinit_struct_audit={.loginuid=INVALID_UID,.sessionid=AUDIT_SID_UNSET,+.contid=AUDIT_CID_UNSET,.ctx=NULL,};
@@ -2112,6 +2114,72 @@ int audit_set_loginuid(kuid_t loginuid)}/**+*audit_set_contid-setcurrenttask'saudit_contextcontid+*@contid:contidvalue+*+*Returns0onsuccess,-EPERMonpermissionfailure.+*+*Called(set)fromfs/proc/base.c::proc_contid_write().+*/+intaudit_set_contid(structtask_struct*task,u64contid)+{+u64oldcontid;+intrc=0;+structaudit_buffer*ab;+uid_tuid;+structtty_struct*tty;+charcomm[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);+/* Don't allow the audit containerid to be unset */+if(!audit_contid_valid(contid))+rc=-EINVAL;+/* if we don't have caps, reject */+elseif(!capable(CAP_AUDIT_CONTROL))+rc=-EPERM;+/* if task has children or is not single-threaded, deny */+elseif(!list_empty(&task->children))+rc=-EBUSY;+elseif(!(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)+returnrc;++ab=audit_log_start(audit_context(),GFP_KERNEL,AUDIT_CONTAINER_OP);+if(!ab)+returnrc;++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);+returnrc;+}++/***__audit_mq_open-recordauditdataforaPOSIXMQopen*@oflag:openflag*@mode:modebits
From: Richard Guy Briggs <hidden> Date: 2018-07-31 20:07:39
Add audit container identifier 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>
Acked-by: Serge Hallyn <serge@hallyn.com>
---
include/linux/audit.h | 11 +++++------
kernel/audit.c | 13 +++++++------
kernel/audit.h | 2 ++
kernel/auditsc.c | 21 ++++++++++++++++-----
4 files changed, 30 insertions(+), 17 deletions(-)
@@ -139,6 +139,7 @@ struct audit_net {kuid_taudit_sig_uid=INVALID_UID;pid_taudit_sig_pid=-1;u32audit_sig_sid=0;+u64audit_sig_cid=AUDIT_CID_UNSET;/* Records can be lost in several ways:0)[suppressedinaudit_alloc]
@@ -1488,7 +1495,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *tsaudit_log_proctitle(tsk,context);-audit_log_contid(tsk,context,"task");+audit_log_contid(context,"task",audit_get_contid(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-07-31 20:07:40
Standalone audit records have the timestamp and serial number generated
on the fly and as such are unique, making them standalone. This new
function audit_alloc_local() generates a local audit context that will
be used only for a standalone record and its auxiliary record(s). The
context is discarded immediately after the local associated records are
produced.
Signed-off-by: Richard Guy Briggs <redacted>
Acked-by: Serge Hallyn <serge@hallyn.com>
---
include/linux/audit.h | 8 ++++++++
kernel/audit.h | 1 +
kernel/auditsc.c | 33 ++++++++++++++++++++++++++++-----
3 files changed, 37 insertions(+), 5 deletions(-)
@@ -110,6 +110,7 @@ struct audit_proctitle {structaudit_context{intdummy;/* must be the first element */intin_syscall;/* 1 if task is in a syscall */+boollocal;/* local context needed */enumaudit_statestate,current_state;unsignedintserial;/* serial number for record */intmajor;/* syscall number */
@@ -913,11 +913,13 @@ static inline void audit_free_aux(struct audit_context *context)}}-staticinlinestructaudit_context*audit_alloc_context(enumaudit_statestate)+staticinlinestructaudit_context*audit_alloc_context(enumaudit_statestate,+gfp_tgfpflags){structaudit_context*context;-context=kzalloc(sizeof(*context),GFP_KERNEL);+/* We can be called in atomic context via audit_tg() */+context=kzalloc(sizeof(*context),gfpflags);if(!context)returnNULL;context->state=state;
@@ -970,7 +972,8 @@ int audit_alloc(struct task_struct *tsk)return0;}-if(!(context=audit_alloc_context(state))){+context=audit_alloc_context(state,GFP_KERNEL);+if(!(context)){tsk->audit=NULL;kmem_cache_free(audit_task_cache,info);kfree(key);
@@ -991,8 +994,27 @@ struct audit_task_info init_struct_audit = {.ctx=NULL,};-staticinlinevoidaudit_free_context(structaudit_context*context)+structaudit_context*audit_alloc_local(gfp_tgfpflags){+structaudit_context*context;++if(!audit_ever_enabled)+returnNULL;/* Return if not auditing. */++context=audit_alloc_context(AUDIT_RECORD_CONTEXT,gfpflags);+if(!context)+returnNULL;+context->serial=audit_serial();+context->ctime=current_kernel_time64();+context->local=true;+returncontext;+}+EXPORT_SYMBOL(audit_alloc_local);++voidaudit_free_context(structaudit_context*context)+{+if(!context)+return;audit_free_names(context);unroll_tree_refs(context,NULL,0);free_tree_refs(context);
@@ -264,6 +264,7 @@#define AUDIT_LOGINUID_SET 24#define AUDIT_SESSIONID 25 /* Session ID */#define AUDIT_FSTYPE 26 /* FileSystem Type */+#define AUDIT_CONTID 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_CONTID:if(f->op!=Audit_not_equal&&f->op!=Audit_equal)return-EINVAL;break;
@@ -1344,6 +1387,10 @@ int audit_filter(int msgtype, unsigned int listtype)result=audit_comparator(audit_loginuid_set(current),f->op,f->val);break;+caseAUDIT_CONTID:+result=audit_comparator64(audit_get_contid(current),+f->op,f->val64);+break;caseAUDIT_MSGTYPE:result=audit_comparator(msgtype,f->op,f->val);break;
From: Richard Guy Briggs <hidden> Date: 2018-07-31 20:07:43
Audit events could happen in a network namespace outside of a task
context due to packets received from the net that trigger an auditing
rule prior to being associated with a running task. The network
namespace could in use by multiple containers by association to the
tasks in that network namespace. We still want a way to attribute
these events to any potential containers. Keep a list per network
namespace to track these audit container identifiiers.
Add/increment the audit container identifier on:
- initial setting of the audit container identifier via /proc
- clone/fork call that inherits an audit container identifier
- unshare call that inherits an audit container identifier
- setns call that inherits an audit container identifier
Delete/decrement the audit container identifier on:
- an inherited audit container identifier dropped when child set
- process exit
- unshare call that drops a net namespace
- setns call that drops a net namespace
See: https://github.com/linux-audit/audit-kernel/issues/92
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>
---
include/linux/audit.h | 17 ++++++++++
kernel/audit.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/auditsc.c | 8 ++++-
kernel/nsproxy.c | 4 +++
4 files changed, 114 insertions(+), 1 deletion(-)
@@ -1547,6 +1631,8 @@ static int __net_init audit_net_init(struct net *net)return-ENOMEM;}aunet->sk->sk_sndtimeo=MAX_SCHEDULE_TIMEOUT;+INIT_LIST_HEAD(&aunet->contid_list);+spin_lock_init(&aunet->contid_list_lock);return0;}
@@ -1488,10 +1488,13 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *tsaudit_log_proctitle(tsk,context);+audit_log_contid(tsk,context,"task");+/* Send end of event record to help user space know we are finished */ab=audit_log_start(context,GFP_KERNEL,AUDIT_EOE);if(ab)audit_log_end(ab);+if(call_panic)audit_panic("error converting sid to string");}
@@ -392,6 +392,32 @@ void audit_switch_task_namespaces(struct nsproxy *ns, struct task_struct *p)audit_netns_contid_add(new->net_ns,contid);}+voidaudit_log_netns_contid_list(structnet*net,structaudit_context*context)+{+spinlock_t*lock=audit_get_netns_contid_list_lock(net);+structaudit_buffer*ab;+structaudit_contid*cont;+boolfirst=true;++/* Generate AUDIT_CONTAINER record with container ID CSV list */+ab=audit_log_start(context,GFP_ATOMIC,AUDIT_CONTAINER);+if(!ab){+audit_log_lost("out of memory in audit_log_netns_contid_list");+return;+}+audit_log_format(ab,"contid=");+spin_lock(lock);+list_for_each_entry(cont,audit_get_netns_contid_list(net),list){+if(!first)+audit_log_format(ab,",");+audit_log_format(ab,"%llu",cont->id);+first=false;+}+spin_unlock(lock);+audit_log_end(ab);+}+EXPORT_SYMBOL(audit_log_netns_contid_list);+voidaudit_panic(constchar*message){switch(audit_failure){
From: Richard Guy Briggs <hidden> Date: 2018-07-31 21:53:52
Add support for reading the audit container identifier from the proc
filesystem.
This is a read from the proc entry of the form
/proc/PID/audit_containerid where PID is the process ID of the task
whose audit container identifier is sought.
The read expects up to a u64 value (unset: 18446744073709551615).
This read requires CAP_AUDIT_CONTROL.
Signed-off-by: Richard Guy Briggs <redacted>
Acked-by: Serge Hallyn <serge@hallyn.com>
---
fs/proc/base.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
From: Steve Grubb <hidden> Date: 2018-08-24 19:36:37
On Tuesday, July 31, 2018 4:07:37 PM EDT Richard Guy Briggs wrote:
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
The "op" field indicates an initial set.
The op field seems to be entirely unnecessary. There is no unset event (nor
should there be) so op=set is implied by the record type. Otherwise the event
format looks fine.
-Steve
quoted hunk
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.
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(+)
@@ -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_OP 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 */
@@ -468,6 +469,7 @@ struct audit_tty_status { #define AUDIT_UID_UNSET (unsigned int)-1 #define AUDIT_SID_UNSET ((unsigned int)-1)+#define AUDIT_CID_UNSET ((u64)-1) /* audit_rule_data supports filter rules with both integer and string * fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
@@ -956,6 +956,7 @@ int audit_alloc(struct task_struct *tsk)return-ENOMEM;info->loginuid=audit_get_loginuid(current);info->sessionid=audit_get_sessionid(current);+info->contid=audit_get_contid(current);tsk->audit=info;if(likely(!audit_ever_enabled))
@@ -985,6 +986,7 @@ int audit_alloc(struct task_struct *tsk)structaudit_task_infoinit_struct_audit={.loginuid=INVALID_UID,.sessionid=AUDIT_SID_UNSET,+.contid=AUDIT_CID_UNSET,.ctx=NULL,};
@@ -2112,6 +2114,72 @@ int audit_set_loginuid(kuid_t loginuid)}/**+*audit_set_contid-setcurrenttask'saudit_contextcontid+*@contid:contidvalue+*+*Returns0onsuccess,-EPERMonpermissionfailure.+*+*Called(set)fromfs/proc/base.c::proc_contid_write().+*/+intaudit_set_contid(structtask_struct*task,u64contid)+{+u64oldcontid;+intrc=0;+structaudit_buffer*ab;+uid_tuid;+structtty_struct*tty;+charcomm[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);+/* Don't allow the audit containerid to be unset */+if(!audit_contid_valid(contid))+rc=-EINVAL;+/* if we don't have caps, reject */+elseif(!capable(CAP_AUDIT_CONTROL))+rc=-EPERM;+/* if task has children or is not single-threaded, deny */+elseif(!list_empty(&task->children))+rc=-EBUSY;+elseif(!(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)+returnrc;++ab=audit_log_start(audit_context(),GFP_KERNEL,AUDIT_CONTAINER_OP);+if(!ab)+returnrc;++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
*context, struct task_struct *ts
audit_log_proctitle(tsk, context);
+ audit_log_contid(tsk, context, "task");
+
/* Send end of event record to help user space know we are finished */
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
if (ab)
audit_log_end(ab);
+
if (call_panic)
audit_panic("error converting sid to string");
}
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-19 23:15:56
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API.
Collect the existing loginuid, sessionid and audit_context together in a
new struct audit_task_info called "audit" in struct task_struct.
Use kmem_cache to manage this pool of memory.
Un-inline audit_free() to be able to always recover that memory.
See: https://github.com/linux-audit/audit-kernel/issues/81
Signed-off-by: Richard Guy Briggs <redacted>
---
include/linux/audit.h | 34 ++++++++++++++++++++++++----------
include/linux/sched.h | 5 +----
init/init_task.c | 3 +--
init/main.c | 2 ++
kernel/auditsc.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
kernel/fork.c | 4 +++-
6 files changed, 73 insertions(+), 26 deletions(-)
@@ -219,8 +219,15 @@ static inline void audit_log_task_info(struct audit_buffer *ab,/* These are defined in auditsc.c *//* Public API */+structaudit_task_info{+kuid_tloginuid;+unsignedintsessionid;+structaudit_context*ctx;+};
Prior to this patch audit_context was available regardless of
CONFIG_AUDITSYSCALL, after this patch the corresponding audit_context
is only available when CONFIG_AUDITSYSCALL is defined.
This is somewhat related to the CONFIG_AUDITSYSCALL comment above, but
since the audit_task_info contains generic audit state (not just
syscall related state), it seems like this, and the audit_task_info
accessors/helpers, should live in kernel/audit.c.
There are probably a few other things that should move to
kernel/audit.c too, e.g. audit_alloc(). Have you verified that this
builds/runs correctly on architectures that define CONFIG_AUDIT but
not CONFIG_AUDITSYSCALL?
quoted hunk
/**
* audit_alloc - allocate an audit context block for a task
* @tsk: task
@@ -940,17 +949,28 @@ int audit_alloc(struct task_struct *tsk) struct audit_context *context; enum audit_state state; char *key = NULL;+ struct audit_task_info *info;++ info = kmem_cache_zalloc(audit_task_cache, GFP_KERNEL);+ if (!info)+ return -ENOMEM;+ info->loginuid = audit_get_loginuid(current);+ info->sessionid = audit_get_sessionid(current);+ tsk->audit = info; if (likely(!audit_ever_enabled)) return 0; /* Return if not auditing. */
I don't view this as necessary for initial acceptance, and
synchronization/locking might render this undesirable, but it would be
curious to see if we could do something clever with refcnts and
copy-on-write to minimize the number of kmem_cache objects in use in
the !audit_ever_enabled (and possibly the AUDIT_DISABLED) case.
state = audit_filter_task(tsk, &key);
if (state == AUDIT_DISABLED) {
+ audit_set_context(tsk, NULL);
It's already NULL, isn't it?
quoted hunk
clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
return 0;
}
if (!(context = audit_alloc_context(state))) {
+ tsk->audit = NULL;
+ kmem_cache_free(audit_task_cache, info);
kfree(key);
audit_log_lost("out of memory in audit_alloc");
return -ENOMEM;
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-19 23:18:23
On Tue, Jul 31, 2018 at 4:12 PM Richard Guy Briggs [off-list ref] wrote:
Audit events could happen in a network namespace outside of a task
context due to packets received from the net that trigger an auditing
rule prior to being associated with a running task. The network
namespace could in use by multiple containers by association to the
tasks in that network namespace. We still want a way to attribute
these events to any potential containers. Keep a list per network
namespace to track these audit container identifiiers.
Add/increment the audit container identifier on:
- initial setting of the audit container identifier via /proc
- clone/fork call that inherits an audit container identifier
- unshare call that inherits an audit container identifier
- setns call that inherits an audit container identifier
Delete/decrement the audit container identifier on:
- an inherited audit container identifier dropped when child set
- process exit
- unshare call that drops a net namespace
- setns call that drops a net namespace
See: https://github.com/linux-audit/audit-kernel/issues/92
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>
---
include/linux/audit.h | 17 ++++++++++
kernel/audit.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/auditsc.c | 8 ++++-
kernel/nsproxy.c | 4 +++
4 files changed, 114 insertions(+), 1 deletion(-)
...
quoted hunk
@@ -308,6 +312,86 @@ static struct sock *audit_get_sk(const struct net *net) return aunet->sk; }+/**+ * audit_get_netns_contid_list - Return the audit container ID list for the given network namespace+ * @net: the destination network namespace+ *+ * Description:+ * Returns the list pointer if valid, NULL otherwise. The caller must ensure+ * that a reference is held for the network namespace while the sock is in use.+ */+struct list_head *audit_get_netns_contid_list(const struct net *net)+{+ struct audit_net *aunet = net_generic(net, audit_net_id);++ return &aunet->contid_list;+}++spinlock_t *audit_get_netns_contid_list_lock(const struct net *net)+{+ struct audit_net *aunet = net_generic(net, audit_net_id);++ return &aunet->contid_list_lock;+}
Instead of returning the spinlock, just do away with the
audit_get_ns_contid_list_lock() function and create two separate lock
and unlock functions that basically do the net_generic() and spinlock
operations together, for example:
static int audit_netns_contid_lock(const struct net *net)
{
aunet = net_generic(net, audit_net_id);
if (!aunet)
return -whatever;
spin_lock(aunet->lock);
return 0;
}
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-20 03:46:15
On Tue, Jul 31, 2018 at 4:11 PM Richard Guy Briggs [off-list ref] wrote:
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.
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.
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-20 03:48:32
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.
From: Richard Guy Briggs <hidden> Date: 2018-10-20 05:59:02
On 2018-10-19 15:38, Paul Moore 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.
Yup, thanks.
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.
@@ -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?
Yup, I had gone through the logic and at first I had doubts, but the
function comments and other usage reassured me (as well as in-kernel
lock checks on boot) that this was the right order and approach.
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
- 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-10-20 07:24:59
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
Create a new audit record AUDIT_CONTAINER to document the audit
container identifier of a process if it is present.
Called from audit_log_exit(), syscalls are covered.
A sample raw event:
type=SYSCALL msg=audit(1519924845.499:257): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=56374e1cef30 a2=241 a3=1b6 items=2 ppid=606 pid=635 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=3 comm="bash" exe="/usr/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="tmpcontainerid"
type=CWD msg=audit(1519924845.499:257): cwd="/root"
type=PATH msg=audit(1519924845.499:257): item=0 name="/tmp/" inode=13863 dev=00:27 mode=041777 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype= PARENT cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PATH msg=audit(1519924845.499:257): item=1 name="/tmp/tmpcontainerid" inode=17729 dev=00:27 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PROCTITLE msg=audit(1519924845.499:257): proctitle=62617368002D6300736C65657020313B206563686F2074657374203E202F746D702F746D70636F6E7461696E65726964
type=CONTAINER msg=audit(1519924845.499:257): op=task contid=123458
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>
---
include/linux/audit.h | 7 +++++++
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 24 ++++++++++++++++++++++++
kernel/auditsc.c | 3 +++
4 files changed, 35 insertions(+)
...
quoted hunk
@@ -2045,6 +2045,30 @@ void audit_log_session_info(struct audit_buffer *ab) audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); }+/*+ * audit_log_contid - report container info+ * @tsk: task to be recorded+ * @context: task or local context for record+ * @op: contid string description+ */+int audit_log_contid(struct task_struct *tsk,+ struct audit_context *context, char *op)+{+ struct audit_buffer *ab;++ if (!audit_contid_set(tsk))+ return 0;+ /* Generate AUDIT_CONTAINER record with container ID */+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER);+ if (!ab)+ return -ENOMEM;+ audit_log_format(ab, "op=%s contid=%llu",+ op, audit_get_contid(tsk));+ audit_log_end(ab);+ return 0;+}+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I prefer
AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If you feel strongly
about keeping it as-is with AUDIT_CONTAINER I suppose I could live
with that, but it is isn't my first choice.
However, I do care about the "op" field in this record. It just
doesn't make any sense; the way you are using it it is more of a
context field than an operations field, and even then why is the
context important from a logging and/or security perspective? Drop it
please.
--
paul moore
www.paul-moore.com
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-20 07:25:14
On Tue, Jul 31, 2018 at 4:11 PM Richard Guy Briggs [off-list ref] wrote:
Add audit container identifier 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>
Acked-by: Serge Hallyn <serge@hallyn.com>
---
include/linux/audit.h | 11 +++++------
kernel/audit.c | 13 +++++++------
kernel/audit.h | 2 ++
kernel/auditsc.c | 21 ++++++++++++++++-----
4 files changed, 30 insertions(+), 17 deletions(-)
@@ -2047,23 +2049,22 @@ void audit_log_session_info(struct audit_buffer *ab) /* * audit_log_contid - report container info- * @tsk: task to be recorded * @context: task or local context for record * @op: contid string description+ * @contid: container ID to report */-int audit_log_contid(struct task_struct *tsk,- struct audit_context *context, char *op)+int audit_log_contid(struct audit_context *context,+ char *op, u64 contid) { struct audit_buffer *ab;- if (!audit_contid_set(tsk))+ if (!audit_contid_valid(contid)) return 0; /* Generate AUDIT_CONTAINER record with container ID */ ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER); if (!ab) return -ENOMEM;- audit_log_format(ab, "op=%s contid=%llu",- op, audit_get_contid(tsk));+ audit_log_format(ab, "op=%s contid=%llu", op, contid); audit_log_end(ab); return 0; }
My previous comments still apply: these audit_log_contid() changes
should be done earlier in the patchset when you first define
audit_log_contid().
--
paul moore
www.paul-moore.com
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-20 07:25:38
On Sun, Aug 5, 2018 at 4:33 AM Richard Guy Briggs [off-list ref] wrote:
Standalone audit records have the timestamp and serial number generated
on the fly and as such are unique, making them standalone. This new
function audit_alloc_local() generates a local audit context that will
be used only for a standalone record and its auxiliary record(s). The
context is discarded immediately after the local associated records are
produced.
Signed-off-by: Richard Guy Briggs <redacted>
Acked-by: Serge Hallyn <serge@hallyn.com>
---
include/linux/audit.h | 8 ++++++++
kernel/audit.h | 1 +
kernel/auditsc.c | 33 ++++++++++++++++++++++++++++-----
3 files changed, 37 insertions(+), 5 deletions(-)
I'm not in love with the local flag, and the whole local context in
general, but that's a larger discussion and not something I want to
force on this patchset; we can fix it later.
I think this patch looks fine, but it seems a bit odd standalone; it's
almost always better to include new capabilities/functions in the same
patch as the user. Since the only user is the networking bits, it
might make more sense to fold this patch into that one.
@@ -110,6 +110,7 @@ struct audit_proctitle {structaudit_context{intdummy;/* must be the first element */intin_syscall;/* 1 if task is in a syscall */+boollocal;/* local context needed */enumaudit_statestate,current_state;unsignedintserial;/* serial number for record */intmajor;/* syscall number */
@@ -913,11 +913,13 @@ static inline void audit_free_aux(struct audit_context *context)}}-staticinlinestructaudit_context*audit_alloc_context(enumaudit_statestate)+staticinlinestructaudit_context*audit_alloc_context(enumaudit_statestate,+gfp_tgfpflags){structaudit_context*context;-context=kzalloc(sizeof(*context),GFP_KERNEL);+/* We can be called in atomic context via audit_tg() */+context=kzalloc(sizeof(*context),gfpflags);if(!context)returnNULL;context->state=state;
@@ -970,7 +972,8 @@ int audit_alloc(struct task_struct *tsk)return0;}-if(!(context=audit_alloc_context(state))){+context=audit_alloc_context(state,GFP_KERNEL);+if(!(context)){tsk->audit=NULL;kmem_cache_free(audit_task_cache,info);kfree(key);
@@ -991,8 +994,27 @@ struct audit_task_info init_struct_audit = {.ctx=NULL,};-staticinlinevoidaudit_free_context(structaudit_context*context)+structaudit_context*audit_alloc_local(gfp_tgfpflags){+structaudit_context*context;++if(!audit_ever_enabled)+returnNULL;/* Return if not auditing. */++context=audit_alloc_context(AUDIT_RECORD_CONTEXT,gfpflags);+if(!context)+returnNULL;+context->serial=audit_serial();+context->ctime=current_kernel_time64();+context->local=true;+returncontext;+}+EXPORT_SYMBOL(audit_alloc_local);++voidaudit_free_context(structaudit_context*context)+{+if(!context)+return;audit_free_names(context);unroll_tree_refs(context,NULL,0);free_tree_refs(context);
Since I never polished up my task_struct/current fix patch enough to
get it past RFC status during this development window (new job, stolen
laptop, etc.) *and* it looks like you are going to need at least one
more respin of this patchset, go ahead and fix this patch to use
current instead of generating a local context. I'll deal with the
merge fallout if/when it happens.
Local contexts are a last resort. If you ever find yourself writing
code that generates a local context, you should first be 100% certain
that the event is not the the result of a process initiated action (in
which case it should take from the task's context).
--
paul moore
www.paul-moore.com
@@ -392,6 +392,32 @@ void audit_switch_task_namespaces(struct nsproxy *ns, struct task_struct *p)audit_netns_contid_add(new->net_ns,contid);}+voidaudit_log_netns_contid_list(structnet*net,structaudit_context*context)+{+spinlock_t*lock=audit_get_netns_contid_list_lock(net);+structaudit_buffer*ab;+structaudit_contid*cont;+boolfirst=true;++/* Generate AUDIT_CONTAINER record with container ID CSV list */+ab=audit_log_start(context,GFP_ATOMIC,AUDIT_CONTAINER);+if(!ab){+audit_log_lost("out of memory in audit_log_netns_contid_list");+return;+}+audit_log_format(ab,"contid=");+spin_lock(lock);+list_for_each_entry(cont,audit_get_netns_contid_list(net),list){+if(!first)+audit_log_format(ab,",");+audit_log_format(ab,"%llu",cont->id);+first=false;+}+spin_unlock(lock);
This is looking like potentially a lot of work to be doing under a
spinlock, not to mention a single spinlock that is shared across CPUs.
Considering that I expect changes to the list to be somewhat
infrequent, this might be a good candidate for a RCU based locking
scheme.
From: Richard Guy Briggs <hidden> Date: 2018-10-24 15:14:39
On 2018-10-19 19:16, Paul Moore wrote:
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
quoted
Create a new audit record AUDIT_CONTAINER to document the audit
container identifier of a process if it is present.
Called from audit_log_exit(), syscalls are covered.
A sample raw event:
type=SYSCALL msg=audit(1519924845.499:257): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=56374e1cef30 a2=241 a3=1b6 items=2 ppid=606 pid=635 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=3 comm="bash" exe="/usr/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="tmpcontainerid"
type=CWD msg=audit(1519924845.499:257): cwd="/root"
type=PATH msg=audit(1519924845.499:257): item=0 name="/tmp/" inode=13863 dev=00:27 mode=041777 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype= PARENT cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PATH msg=audit(1519924845.499:257): item=1 name="/tmp/tmpcontainerid" inode=17729 dev=00:27 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PROCTITLE msg=audit(1519924845.499:257): proctitle=62617368002D6300736C65657020313B206563686F2074657374203E202F746D702F746D70636F6E7461696E65726964
type=CONTAINER msg=audit(1519924845.499:257): op=task contid=123458
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>
---
include/linux/audit.h | 7 +++++++
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 24 ++++++++++++++++++++++++
kernel/auditsc.c | 3 +++
4 files changed, 35 insertions(+)
...
quoted
@@ -2045,6 +2045,30 @@ void audit_log_session_info(struct audit_buffer *ab) audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); }+/*+ * audit_log_contid - report container info+ * @tsk: task to be recorded+ * @context: task or local context for record+ * @op: contid string description+ */+int audit_log_contid(struct task_struct *tsk,+ struct audit_context *context, char *op)+{+ struct audit_buffer *ab;++ if (!audit_contid_set(tsk))+ return 0;+ /* Generate AUDIT_CONTAINER record with container ID */+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER);+ if (!ab)+ return -ENOMEM;+ audit_log_format(ab, "op=%s contid=%llu",+ op, audit_get_contid(tsk));+ audit_log_end(ab);+ return 0;+}+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I prefer
AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If you feel strongly
about keeping it as-is with AUDIT_CONTAINER I suppose I could live
with that, but it is isn't my first choice.
I don't have a strong opinion on this one, mildly preferring the shorter
one only because it is shorter.
Steve? Can you comment on this one way or the other?
However, I do care about the "op" field in this record. It just
doesn't make any sense; the way you are using it it is more of a
context field than an operations field, and even then why is the
context important from a logging and/or security perspective? Drop it
please.
I'll rename it to whatever you like. I'd suggest "ref=". The reason I
think it is important is there are multiple sources that aren't always
obvious from the other records to which it is associated. In the case
of ptrace and signals, there can be many target tasks listed (OBJ_PID)
with no other way to distinguish the matching audit container identifier
records all for one event. This is in addition to the default syscall
container identifier record. I'm not currently happy with the text
content to link the two, but that should be solvable (most obvious is
taret PID). Throwing away this information seems shortsighted.
paul moore
- 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-10-25 05:25:29
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs [off-list ref] wrote:
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
quoted
Create a new audit record AUDIT_CONTAINER to document the audit
container identifier of a process if it is present.
Called from audit_log_exit(), syscalls are covered.
A sample raw event:
type=SYSCALL msg=audit(1519924845.499:257): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=56374e1cef30 a2=241 a3=1b6 items=2 ppid=606 pid=635 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=3 comm="bash" exe="/usr/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="tmpcontainerid"
type=CWD msg=audit(1519924845.499:257): cwd="/root"
type=PATH msg=audit(1519924845.499:257): item=0 name="/tmp/" inode=13863 dev=00:27 mode=041777 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype= PARENT cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PATH msg=audit(1519924845.499:257): item=1 name="/tmp/tmpcontainerid" inode=17729 dev=00:27 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PROCTITLE msg=audit(1519924845.499:257): proctitle=62617368002D6300736C65657020313B206563686F2074657374203E202F746D702F746D70636F6E7461696E65726964
type=CONTAINER msg=audit(1519924845.499:257): op=task contid=123458
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>
---
include/linux/audit.h | 7 +++++++
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 24 ++++++++++++++++++++++++
kernel/auditsc.c | 3 +++
4 files changed, 35 insertions(+)
...
quoted
@@ -2045,6 +2045,30 @@ void audit_log_session_info(struct audit_buffer *ab) audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); }+/*+ * audit_log_contid - report container info+ * @tsk: task to be recorded+ * @context: task or local context for record+ * @op: contid string description+ */+int audit_log_contid(struct task_struct *tsk,+ struct audit_context *context, char *op)+{+ struct audit_buffer *ab;++ if (!audit_contid_set(tsk))+ return 0;+ /* Generate AUDIT_CONTAINER record with container ID */+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER);+ if (!ab)+ return -ENOMEM;+ audit_log_format(ab, "op=%s contid=%llu",+ op, audit_get_contid(tsk));+ audit_log_end(ab);+ return 0;+}+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I prefer
AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If you feel strongly
about keeping it as-is with AUDIT_CONTAINER I suppose I could live
with that, but it is isn't my first choice.
I don't have a strong opinion on this one, mildly preferring the shorter
one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it seems as
though we should use "AUDIT_CONTAINER" as a prefix of sorts, rather
than a type itself.
quoted
However, I do care about the "op" field in this record. It just
doesn't make any sense; the way you are using it it is more of a
context field than an operations field, and even then why is the
context important from a logging and/or security perspective? Drop it
please.
I'll rename it to whatever you like. I'd suggest "ref=". The reason I
think it is important is there are multiple sources that aren't always
obvious from the other records to which it is associated. In the case
of ptrace and signals, there can be many target tasks listed (OBJ_PID)
with no other way to distinguish the matching audit container identifier
records all for one event. This is in addition to the default syscall
container identifier record. I'm not currently happy with the text
content to link the two, but that should be solvable (most obvious is
taret PID). Throwing away this information seems shortsighted.
It would be helpful if you could generate real audit events
demonstrating the problems you are describing, as well as a more
standard syscall event, so we can discuss some possible solutions.
--
paul moore
www.paul-moore.com
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-25 06:13:07
On October 25, 2018 1:43:16 AM Richard Guy Briggs [off-list ref] wrote:
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
...
quoted
quoted
quoted
However, I do care about the "op" field in this record. It just
doesn't make any sense; the way you are using it it is more of a
context field than an operations field, and even then why is the
context important from a logging and/or security perspective? Drop it
please.
I'll rename it to whatever you like. I'd suggest "ref=". The reason I
think it is important is there are multiple sources that aren't always
obvious from the other records to which it is associated. In the case
of ptrace and signals, there can be many target tasks listed (OBJ_PID)
with no other way to distinguish the matching audit container identifier
records all for one event. This is in addition to the default syscall
container identifier record. I'm not currently happy with the text
content to link the two, but that should be solvable (most obvious is
taret PID). Throwing away this information seems shortsighted.
It would be helpful if you could generate real audit events
demonstrating the problems you are describing, as well as a more
standard syscall event, so we can discuss some possible solutions.
If the auditted process is in a container and it ptraces or signals
another process in a container, there will be two AUDIT_CONTAINER
records for the same event that won't be identified as to which record
belongs to which process or other record (SYSCALL vs 1+ OBJ_PID
records). There could be many signals recorded, each with their own
OBJ_PID record. The first is stored in the audit context and additional
ones are stored in a chained struct that can accommodate 16 entries each.
(See audit_signal_info(), __audit_ptrace().)
(As a side note, on code inspection it appears that a signal target
would get overwritten by a ptrace action if they were to happen in that
order.)
As requested above, please respond with real audit events generated by this patchset so that we can discuss possible solutions.
From: Richard Guy Briggs <hidden> Date: 2018-10-25 09:13:35
On 2018-10-24 16:55, Paul Moore wrote:
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
quoted
Create a new audit record AUDIT_CONTAINER to document the audit
container identifier of a process if it is present.
Called from audit_log_exit(), syscalls are covered.
A sample raw event:
type=SYSCALL msg=audit(1519924845.499:257): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=56374e1cef30 a2=241 a3=1b6 items=2 ppid=606 pid=635 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=3 comm="bash" exe="/usr/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="tmpcontainerid"
type=CWD msg=audit(1519924845.499:257): cwd="/root"
type=PATH msg=audit(1519924845.499:257): item=0 name="/tmp/" inode=13863 dev=00:27 mode=041777 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype= PARENT cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PATH msg=audit(1519924845.499:257): item=1 name="/tmp/tmpcontainerid" inode=17729 dev=00:27 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
type=PROCTITLE msg=audit(1519924845.499:257): proctitle=62617368002D6300736C65657020313B206563686F2074657374203E202F746D702F746D70636F6E7461696E65726964
type=CONTAINER msg=audit(1519924845.499:257): op=task contid=123458
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>
---
include/linux/audit.h | 7 +++++++
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 24 ++++++++++++++++++++++++
kernel/auditsc.c | 3 +++
4 files changed, 35 insertions(+)
...
quoted
@@ -2045,6 +2045,30 @@ void audit_log_session_info(struct audit_buffer *ab) audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); }+/*+ * audit_log_contid - report container info+ * @tsk: task to be recorded+ * @context: task or local context for record+ * @op: contid string description+ */+int audit_log_contid(struct task_struct *tsk,+ struct audit_context *context, char *op)+{+ struct audit_buffer *ab;++ if (!audit_contid_set(tsk))+ return 0;+ /* Generate AUDIT_CONTAINER record with container ID */+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER);+ if (!ab)+ return -ENOMEM;+ audit_log_format(ab, "op=%s contid=%llu",+ op, audit_get_contid(tsk));+ audit_log_end(ab);+ return 0;+}+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I prefer
AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If you feel strongly
about keeping it as-is with AUDIT_CONTAINER I suppose I could live
with that, but it is isn't my first choice.
I don't have a strong opinion on this one, mildly preferring the shorter
one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it seems as
though we should use "AUDIT_CONTAINER" as a prefix of sorts, rather
than a type itself.
I'm fine with that. I'd still like to hear Steve's input. He had
stronger opinions than me.
quoted
quoted
However, I do care about the "op" field in this record. It just
doesn't make any sense; the way you are using it it is more of a
context field than an operations field, and even then why is the
context important from a logging and/or security perspective? Drop it
please.
I'll rename it to whatever you like. I'd suggest "ref=". The reason I
think it is important is there are multiple sources that aren't always
obvious from the other records to which it is associated. In the case
of ptrace and signals, there can be many target tasks listed (OBJ_PID)
with no other way to distinguish the matching audit container identifier
records all for one event. This is in addition to the default syscall
container identifier record. I'm not currently happy with the text
content to link the two, but that should be solvable (most obvious is
taret PID). Throwing away this information seems shortsighted.
It would be helpful if you could generate real audit events
demonstrating the problems you are describing, as well as a more
standard syscall event, so we can discuss some possible solutions.
If the auditted process is in a container and it ptraces or signals
another process in a container, there will be two AUDIT_CONTAINER
records for the same event that won't be identified as to which record
belongs to which process or other record (SYSCALL vs 1+ OBJ_PID
records). There could be many signals recorded, each with their own
OBJ_PID record. The first is stored in the audit context and additional
ones are stored in a chained struct that can accommodate 16 entries each.
(See audit_signal_info(), __audit_ptrace().)
(As a side note, on code inspection it appears that a signal target
would get overwritten by a ptrace action if they were to happen in that
order.)
paul moore
- 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-10-25 10:49:50
On Thu, Oct 25, 2018 at 2:06 AM Steve Grubb [off-list ref] wrote:
On Wed, 24 Oct 2018 20:42:55 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs
[off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
...
quoted
quoted
quoted
quoted
quoted
+/*
+ * audit_log_contid - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ * @op: contid string description
+ */
+int audit_log_contid(struct task_struct *tsk,
+ struct audit_context *context,
char *op) +{
+ struct audit_buffer *ab;
+
+ if (!audit_contid_set(tsk))
+ return 0;
+ /* Generate AUDIT_CONTAINER record with container ID
*/
+ ab = audit_log_start(context, GFP_KERNEL,
AUDIT_CONTAINER);
+ if (!ab)
+ return -ENOMEM;
+ audit_log_format(ab, "op=%s contid=%llu",
+ op, audit_get_contid(tsk));
+ audit_log_end(ab);
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I prefer
AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If you feel
strongly about keeping it as-is with AUDIT_CONTAINER I suppose
I could live with that, but it is isn't my first choice.
I don't have a strong opinion on this one, mildly preferring the
shorter one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it seems
as though we should use "AUDIT_CONTAINER" as a prefix of sorts,
rather than a type itself.
I'm fine with that. I'd still like to hear Steve's input. He had
stronger opinions than me.
The creation event should be separate and distinct from the continuing
use when its used as a supplemental record. IOW, binding the ID to a
container is part of the lifecycle and needs to be kept distinct.
Steve's comment is pretty ambiguous when it comes to AUDIT_CONTAINER
vs AUDIT_CONTAINER_ID, but one could argue that AUDIT_CONTAINER_ID
helps distinguish the audit container id marking record and gets to
what I believe is the spirit of Steve's comment. Taking this in
context with my previous remarks, let's switch to using
AUDIT_CONTAINER_ID.
--
paul moore
www.paul-moore.com
audit_buffer *ab) audit_log_format(ab, " auid=%u ses=%u",
auid, sessionid); }
+/*
+ * audit_log_contid - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ * @op: contid string description
+ */
+int audit_log_contid(struct task_struct *tsk,
+ struct audit_context *context,
char *op) +{
+ struct audit_buffer *ab;
+
+ if (!audit_contid_set(tsk))
+ return 0;
+ /* Generate AUDIT_CONTAINER record with container ID
*/
+ ab = audit_log_start(context, GFP_KERNEL,
AUDIT_CONTAINER);
+ if (!ab)
+ return -ENOMEM;
+ audit_log_format(ab, "op=%s contid=%llu",
+ op, audit_get_contid(tsk));
+ audit_log_end(ab);
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I prefer
AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If you feel
strongly about keeping it as-is with AUDIT_CONTAINER I suppose
I could live with that, but it is isn't my first choice.
I don't have a strong opinion on this one, mildly preferring the
shorter one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it seems
as though we should use "AUDIT_CONTAINER" as a prefix of sorts,
rather than a type itself.
I'm fine with that. I'd still like to hear Steve's input. He had
stronger opinions than me.
The creation event should be separate and distinct from the continuing
use when its used as a supplemental record. IOW, binding the ID to a
container is part of the lifecycle and needs to be kept distinct.
-Steve
quoted
quoted
quoted
However, I do care about the "op" field in this record. It just
doesn't make any sense; the way you are using it it is more of a
context field than an operations field, and even then why is the
context important from a logging and/or security perspective?
Drop it please.
I'll rename it to whatever you like. I'd suggest "ref=". The
reason I think it is important is there are multiple sources that
aren't always obvious from the other records to which it is
associated. In the case of ptrace and signals, there can be many
target tasks listed (OBJ_PID) with no other way to distinguish
the matching audit container identifier records all for one
event. This is in addition to the default syscall container
identifier record. I'm not currently happy with the text content
to link the two, but that should be solvable (most obvious is
taret PID). Throwing away this information seems shortsighted.
It would be helpful if you could generate real audit events
demonstrating the problems you are describing, as well as a more
standard syscall event, so we can discuss some possible solutions.
If the auditted process is in a container and it ptraces or signals
another process in a container, there will be two AUDIT_CONTAINER
records for the same event that won't be identified as to which record
belongs to which process or other record (SYSCALL vs 1+ OBJ_PID
records). There could be many signals recorded, each with their own
OBJ_PID record. The first is stored in the audit context and
additional ones are stored in a chained struct that can accommodate
16 entries each.
(See audit_signal_info(), __audit_ptrace().)
(As a side note, on code inspection it appears that a signal target
would get overwritten by a ptrace action if they were to happen in
that order.)
quoted
paul moore
- 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
--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-25 20:40:19
On Thu, Oct 25, 2018 at 1:38 PM Richard Guy Briggs [off-list ref] wrote:
On 2018-10-25 17:57, Steve Grubb wrote:
quoted
On Thu, 25 Oct 2018 08:27:32 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-25 06:49, Paul Moore wrote:
quoted
On Thu, Oct 25, 2018 at 2:06 AM Steve Grubb [off-list ref]
wrote:
quoted
On Wed, 24 Oct 2018 20:42:55 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs
[off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
...
quoted
quoted
quoted
quoted
quoted
quoted
+/*
+ * audit_log_contid - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ * @op: contid string description
+ */
+int audit_log_contid(struct task_struct *tsk,
+ struct audit_context
*context, char *op) +{
+ struct audit_buffer *ab;
+
+ if (!audit_contid_set(tsk))
+ return 0;
+ /* Generate AUDIT_CONTAINER record with
container ID */
+ ab = audit_log_start(context, GFP_KERNEL,
AUDIT_CONTAINER);
+ if (!ab)
+ return -ENOMEM;
+ audit_log_format(ab, "op=%s contid=%llu",
+ op, audit_get_contid(tsk));
+ audit_log_end(ab);
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I
prefer AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If
you feel strongly about keeping it as-is with
AUDIT_CONTAINER I suppose I could live with that, but it
is isn't my first choice.
I don't have a strong opinion on this one, mildly
preferring the shorter one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it
seems as though we should use "AUDIT_CONTAINER" as a prefix
of sorts, rather than a type itself.
I'm fine with that. I'd still like to hear Steve's input. He
had stronger opinions than me.
The creation event should be separate and distinct from the
continuing use when its used as a supplemental record. IOW,
binding the ID to a container is part of the lifecycle and needs
to be kept distinct.
Steve's comment is pretty ambiguous when it comes to AUDIT_CONTAINER
vs AUDIT_CONTAINER_ID, but one could argue that AUDIT_CONTAINER_ID
helps distinguish the audit container id marking record and gets to
what I believe is the spirit of Steve's comment. Taking this in
context with my previous remarks, let's switch to using
AUDIT_CONTAINER_ID.
I suspect Steve is mixing up AUDIT_CONTAINER_OP with
AUDIT_CONTAINER_ID, confusing the fact that they are two seperate
records. As a summary, the suggested records are:
CONTAINER_OP audit container identifier creation
CONTAINER audit container identifier aux record to an
event
and what Paul is suggesting (which is fine by me) is:
CONTAINER_OP audit container identifier creation event
CONTAINER_ID audit container identifier aux record to
an event
Steve, please indicate you are fine with this.
CONTAINER_ID audit container identifier creation event
CONTAINER audit container identifier aux record to an event
Or vice versa. Don't mix up creation of the identifier with operations.
Exactly what I'm trying to avoid... Worded another way: "Don't mix up
the creation operation with routine reporting of the identifier in
events." Steve, can you and Paul discuss and agree on what they should
be called? I don't have a horse in this race, but I need to record the
result of that run. ;-)
See my previous comments, I think I've been pretty clear on what I
would like to see.
--
paul moore
www.paul-moore.com
From: Richard Guy Briggs <hidden> Date: 2018-10-25 20:55:41
On 2018-10-25 07:13, Paul Moore wrote:
On October 25, 2018 1:43:16 AM Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
...
quoted
quoted
quoted
quoted
However, I do care about the "op" field in this record. It just
doesn't make any sense; the way you are using it it is more of a
context field than an operations field, and even then why is the
context important from a logging and/or security perspective? Drop it
please.
I'll rename it to whatever you like. I'd suggest "ref=". The reason I
think it is important is there are multiple sources that aren't always
obvious from the other records to which it is associated. In the case
of ptrace and signals, there can be many target tasks listed (OBJ_PID)
with no other way to distinguish the matching audit container identifier
records all for one event. This is in addition to the default syscall
container identifier record. I'm not currently happy with the text
content to link the two, but that should be solvable (most obvious is
taret PID). Throwing away this information seems shortsighted.
It would be helpful if you could generate real audit events
demonstrating the problems you are describing, as well as a more
standard syscall event, so we can discuss some possible solutions.
If the auditted process is in a container and it ptraces or signals
another process in a container, there will be two AUDIT_CONTAINER
records for the same event that won't be identified as to which record
belongs to which process or other record (SYSCALL vs 1+ OBJ_PID
records). There could be many signals recorded, each with their own
OBJ_PID record. The first is stored in the audit context and additional
ones are stored in a chained struct that can accommodate 16 entries each.
(See audit_signal_info(), __audit_ptrace().)
(As a side note, on code inspection it appears that a signal target
would get overwritten by a ptrace action if they were to happen in that
order.)
As requested above, please respond with real audit events generated by
this patchset so that we can discuss possible solutions.
Ok, then we should be developping a test to test ptrace and signal
auditting in general since we don't have current experience/evidence
that those even work (or rip them out if not).
paul moore
- 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: Richard Guy Briggs <hidden> Date: 2018-10-25 21:00:21
On 2018-10-25 06:49, Paul Moore wrote:
On Thu, Oct 25, 2018 at 2:06 AM Steve Grubb [off-list ref] wrote:
quoted
On Wed, 24 Oct 2018 20:42:55 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs
[off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
...
quoted
quoted
quoted
quoted
quoted
quoted
+/*
+ * audit_log_contid - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ * @op: contid string description
+ */
+int audit_log_contid(struct task_struct *tsk,
+ struct audit_context *context,
char *op) +{
+ struct audit_buffer *ab;
+
+ if (!audit_contid_set(tsk))
+ return 0;
+ /* Generate AUDIT_CONTAINER record with container ID
*/
+ ab = audit_log_start(context, GFP_KERNEL,
AUDIT_CONTAINER);
+ if (!ab)
+ return -ENOMEM;
+ audit_log_format(ab, "op=%s contid=%llu",
+ op, audit_get_contid(tsk));
+ audit_log_end(ab);
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I prefer
AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If you feel
strongly about keeping it as-is with AUDIT_CONTAINER I suppose
I could live with that, but it is isn't my first choice.
I don't have a strong opinion on this one, mildly preferring the
shorter one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it seems
as though we should use "AUDIT_CONTAINER" as a prefix of sorts,
rather than a type itself.
I'm fine with that. I'd still like to hear Steve's input. He had
stronger opinions than me.
The creation event should be separate and distinct from the continuing
use when its used as a supplemental record. IOW, binding the ID to a
container is part of the lifecycle and needs to be kept distinct.
Steve's comment is pretty ambiguous when it comes to AUDIT_CONTAINER
vs AUDIT_CONTAINER_ID, but one could argue that AUDIT_CONTAINER_ID
helps distinguish the audit container id marking record and gets to
what I believe is the spirit of Steve's comment. Taking this in
context with my previous remarks, let's switch to using
AUDIT_CONTAINER_ID.
I suspect Steve is mixing up AUDIT_CONTAINER_OP with AUDIT_CONTAINER_ID,
confusing the fact that they are two seperate records. As a summary,
the suggested records are:
CONTAINER_OP audit container identifier creation
CONTAINER audit container identifier aux record to an event
and what Paul is suggesting (which is fine by me) is:
CONTAINER_OP audit container identifier creation event
CONTAINER_ID audit container identifier aux record to an event
Steve, please indicate you are fine with this.
paul moore
- 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: Steve Grubb <hidden> Date: 2018-10-26 00:31:18
On Thu, 25 Oct 2018 08:27:32 -0400
Richard Guy Briggs [off-list ref] wrote:
On 2018-10-25 06:49, Paul Moore wrote:
quoted
On Thu, Oct 25, 2018 at 2:06 AM Steve Grubb [off-list ref]
wrote:
quoted
On Wed, 24 Oct 2018 20:42:55 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs
[off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
...
quoted
quoted
quoted
quoted
quoted
quoted
+/*
+ * audit_log_contid - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ * @op: contid string description
+ */
+int audit_log_contid(struct task_struct *tsk,
+ struct audit_context
*context, char *op) +{
+ struct audit_buffer *ab;
+
+ if (!audit_contid_set(tsk))
+ return 0;
+ /* Generate AUDIT_CONTAINER record with
container ID */
+ ab = audit_log_start(context, GFP_KERNEL,
AUDIT_CONTAINER);
+ if (!ab)
+ return -ENOMEM;
+ audit_log_format(ab, "op=%s contid=%llu",
+ op, audit_get_contid(tsk));
+ audit_log_end(ab);
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I
prefer AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If
you feel strongly about keeping it as-is with
AUDIT_CONTAINER I suppose I could live with that, but it
is isn't my first choice.
I don't have a strong opinion on this one, mildly
preferring the shorter one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it
seems as though we should use "AUDIT_CONTAINER" as a prefix
of sorts, rather than a type itself.
I'm fine with that. I'd still like to hear Steve's input. He
had stronger opinions than me.
The creation event should be separate and distinct from the
continuing use when its used as a supplemental record. IOW,
binding the ID to a container is part of the lifecycle and needs
to be kept distinct.
Steve's comment is pretty ambiguous when it comes to AUDIT_CONTAINER
vs AUDIT_CONTAINER_ID, but one could argue that AUDIT_CONTAINER_ID
helps distinguish the audit container id marking record and gets to
what I believe is the spirit of Steve's comment. Taking this in
context with my previous remarks, let's switch to using
AUDIT_CONTAINER_ID.
I suspect Steve is mixing up AUDIT_CONTAINER_OP with
AUDIT_CONTAINER_ID, confusing the fact that they are two seperate
records. As a summary, the suggested records are:
CONTAINER_OP audit container identifier creation
CONTAINER audit container identifier aux record to an
event
and what Paul is suggesting (which is fine by me) is:
CONTAINER_OP audit container identifier creation event
CONTAINER_ID audit container identifier aux record to
an event
Steve, please indicate you are fine with this.
I thought it was:
CONTAINER_ID audit container identifier creation event
CONTAINER audit container identifier aux record to an event
Or vice versa. Don't mix up creation of the identifier with operations.
-Steve
From: Richard Guy Briggs <hidden> Date: 2018-10-26 02:12:34
On 2018-10-25 17:57, Steve Grubb wrote:
On Thu, 25 Oct 2018 08:27:32 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-25 06:49, Paul Moore wrote:
quoted
On Thu, Oct 25, 2018 at 2:06 AM Steve Grubb [off-list ref]
wrote:
quoted
On Wed, 24 Oct 2018 20:42:55 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs
[off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
...
quoted
quoted
quoted
quoted
quoted
quoted
+/*
+ * audit_log_contid - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ * @op: contid string description
+ */
+int audit_log_contid(struct task_struct *tsk,
+ struct audit_context
*context, char *op) +{
+ struct audit_buffer *ab;
+
+ if (!audit_contid_set(tsk))
+ return 0;
+ /* Generate AUDIT_CONTAINER record with
container ID */
+ ab = audit_log_start(context, GFP_KERNEL,
AUDIT_CONTAINER);
+ if (!ab)
+ return -ENOMEM;
+ audit_log_format(ab, "op=%s contid=%llu",
+ op, audit_get_contid(tsk));
+ audit_log_end(ab);
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the patch, I
prefer AUDIT_CONTAINER_ID here over AUDIT_CONTAINER. If
you feel strongly about keeping it as-is with
AUDIT_CONTAINER I suppose I could live with that, but it
is isn't my first choice.
I don't have a strong opinion on this one, mildly
preferring the shorter one only because it is shorter.
We already have multiple AUDIT_CONTAINER* record types, so it
seems as though we should use "AUDIT_CONTAINER" as a prefix
of sorts, rather than a type itself.
I'm fine with that. I'd still like to hear Steve's input. He
had stronger opinions than me.
The creation event should be separate and distinct from the
continuing use when its used as a supplemental record. IOW,
binding the ID to a container is part of the lifecycle and needs
to be kept distinct.
Steve's comment is pretty ambiguous when it comes to AUDIT_CONTAINER
vs AUDIT_CONTAINER_ID, but one could argue that AUDIT_CONTAINER_ID
helps distinguish the audit container id marking record and gets to
what I believe is the spirit of Steve's comment. Taking this in
context with my previous remarks, let's switch to using
AUDIT_CONTAINER_ID.
I suspect Steve is mixing up AUDIT_CONTAINER_OP with
AUDIT_CONTAINER_ID, confusing the fact that they are two seperate
records. As a summary, the suggested records are:
CONTAINER_OP audit container identifier creation
CONTAINER audit container identifier aux record to an
event
and what Paul is suggesting (which is fine by me) is:
CONTAINER_OP audit container identifier creation event
CONTAINER_ID audit container identifier aux record to
an event
Steve, please indicate you are fine with this.
CONTAINER_ID audit container identifier creation event
CONTAINER audit container identifier aux record to an event
Or vice versa. Don't mix up creation of the identifier with operations.
Exactly what I'm trying to avoid... Worded another way: "Don't mix up
the creation operation with routine reporting of the identifier in
events." Steve, can you and Paul discuss and agree on what they should
be called? I don't have a horse in this race, but I need to record the
result of that run. ;-)
-Steve
- 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: Steve Grubb <hidden> Date: 2018-10-26 06:30:12
On Thu, 25 Oct 2018 16:40:19 -0400
Paul Moore [off-list ref] wrote:
On Thu, Oct 25, 2018 at 1:38 PM Richard Guy Briggs [off-list ref]
wrote:
quoted
On 2018-10-25 17:57, Steve Grubb wrote:
quoted
On Thu, 25 Oct 2018 08:27:32 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-25 06:49, Paul Moore wrote:
quoted
On Thu, Oct 25, 2018 at 2:06 AM Steve Grubb
[off-list ref] wrote:
quoted
On Wed, 24 Oct 2018 20:42:55 -0400
Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-24 16:55, Paul Moore wrote:
quoted
On Wed, Oct 24, 2018 at 11:15 AM Richard Guy Briggs
[off-list ref] wrote:
quoted
On 2018-10-19 19:16, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
...
quoted
quoted
quoted
quoted
quoted
quoted
+/*
+ * audit_log_contid - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ * @op: contid string description
+ */
+int audit_log_contid(struct task_struct *tsk,
+ struct audit_context
*context, char *op) +{
+ struct audit_buffer *ab;
+
+ if (!audit_contid_set(tsk))
+ return 0;
+ /* Generate AUDIT_CONTAINER record with
container ID */
+ ab = audit_log_start(context, GFP_KERNEL,
AUDIT_CONTAINER);
+ if (!ab)
+ return -ENOMEM;
+ audit_log_format(ab, "op=%s contid=%llu",
+ op,
audit_get_contid(tsk));
+ audit_log_end(ab);
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_contid);
As discussed in the previous iteration of the
patch, I prefer AUDIT_CONTAINER_ID here over
AUDIT_CONTAINER. If you feel strongly about
keeping it as-is with AUDIT_CONTAINER I suppose I
could live with that, but it is isn't my first
choice.
I don't have a strong opinion on this one, mildly
preferring the shorter one only because it is
shorter.
We already have multiple AUDIT_CONTAINER* record types,
so it seems as though we should use "AUDIT_CONTAINER"
as a prefix of sorts, rather than a type itself.
I'm fine with that. I'd still like to hear Steve's
input. He had stronger opinions than me.
The creation event should be separate and distinct from the
continuing use when its used as a supplemental record. IOW,
binding the ID to a container is part of the lifecycle and
needs to be kept distinct.
Steve's comment is pretty ambiguous when it comes to
AUDIT_CONTAINER vs AUDIT_CONTAINER_ID, but one could argue
that AUDIT_CONTAINER_ID helps distinguish the audit container
id marking record and gets to what I believe is the spirit of
Steve's comment. Taking this in context with my previous
remarks, let's switch to using AUDIT_CONTAINER_ID.
I suspect Steve is mixing up AUDIT_CONTAINER_OP with
AUDIT_CONTAINER_ID, confusing the fact that they are two
seperate records. As a summary, the suggested records are:
CONTAINER_OP audit container identifier creation
CONTAINER audit container identifier aux record to an
event
and what Paul is suggesting (which is fine by me) is:
CONTAINER_OP audit container identifier creation event
CONTAINER_ID audit container identifier aux record to
an event
Steve, please indicate you are fine with this.
CONTAINER_ID audit container identifier creation event
event. CONTAINER audit container identifier aux record to an
event
Or vice versa. Don't mix up creation of the identifier with
operations.
Exactly what I'm trying to avoid... Worded another way: "Don't mix
up the creation operation with routine reporting of the identifier
in events." Steve, can you and Paul discuss and agree on what they
should be called? I don't have a horse in this race, but I need to
record the result of that run. ;-)
See my previous comments, I think I've been pretty clear on what I
would like to see.
And historically speaking setting audit loginuid produces a LOGIN
event, so it only makes sense to consider binding container ID to
container as a CONTAINER event. For other supplemental records, we name
things what they are: PATH, CWD, SOCKADDR, etc. So, CONTAINER_ID makes
sense. CONTAINER_OP sounds like its for operations on a container. Do
we have any operations on a container?
-Steve
...
And historically speaking setting audit loginuid produces a LOGIN
event, so it only makes sense to consider binding container ID to
container as a CONTAINER event. For other supplemental records, we name
things what they are: PATH, CWD, SOCKADDR, etc. So, CONTAINER_ID makes
sense. CONTAINER_OP sounds like its for operations on a container. Do
we have any operations on a container?
The answer has to be "no", because containers are, by emphatic assertion,
not kernel constructs. Any CONTAINER_OP event has to come from user space.
I think.
From: Paul Moore <paul@paul-moore.com> Date: 2018-10-28 16:37:50
On Fri, Oct 26, 2018 at 4:13 AM Casey Schaufler [off-list ref] wrote:
On 10/25/2018 2:55 PM, Steve Grubb wrote:
quoted
...
And historically speaking setting audit loginuid produces a LOGIN
event, so it only makes sense to consider binding container ID to
container as a CONTAINER event. For other supplemental records, we name
things what they are: PATH, CWD, SOCKADDR, etc. So, CONTAINER_ID makes
sense. CONTAINER_OP sounds like its for operations on a container. Do
we have any operations on a container?
The answer has to be "no", because containers are, by emphatic assertion,
not kernel constructs. Any CONTAINER_OP event has to come from user space.
I think.
It is very important that we do not confuse operations on the audit
container id with operations on the containers themselves. Of course
at a higher level, e.g. audit log analysis, we want to equate the two,
and if the container runtime which manages the audit container id is
sane that should be a reasonable assumption, but in this particular
patchset AUDIT_CONTAINER_OP is referring to operations involving just
the audit container id.
If there is a need for additional container operation auditing (note
well that I did not say audit container id here) then those audit
records can, and should, be generated by the container runtime itself,
similar to what we do with libvirt for virtualization.
--
paul moore
www.paul-moore.com
From: Richard Guy Briggs <hidden> Date: 2018-11-01 22:07:44
On 2018-10-19 19:15, Paul Moore wrote:
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
quoted
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API.
Collect the existing loginuid, sessionid and audit_context together in a
new struct audit_task_info called "audit" in struct task_struct.
Use kmem_cache to manage this pool of memory.
Un-inline audit_free() to be able to always recover that memory.
See: https://github.com/linux-audit/audit-kernel/issues/81
Signed-off-by: Richard Guy Briggs <redacted>
---
include/linux/audit.h | 34 ++++++++++++++++++++++++----------
include/linux/sched.h | 5 +----
init/init_task.c | 3 +--
init/main.c | 2 ++
kernel/auditsc.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
kernel/fork.c | 4 +++-
6 files changed, 73 insertions(+), 26 deletions(-)
@@ -219,8 +219,15 @@ static inline void audit_log_task_info(struct audit_buffer *ab,/* These are defined in auditsc.c *//* Public API */+structaudit_task_info{+kuid_tloginuid;+unsignedintsessionid;+structaudit_context*ctx;+};
Prior to this patch audit_context was available regardless of
CONFIG_AUDITSYSCALL, after this patch the corresponding audit_context
is only available when CONFIG_AUDITSYSCALL is defined.
This was intentional since audit_context is not used when AUDITSYSCALL is
disabled. audit_alloc() was stubbed in that case to return 0. audit_context()
returned NULL.
The fact that audit_context was still present in struct task_struct was an
oversight in the two patches already accepted:
("audit: use inline function to get audit context")
("audit: use inline function to get audit context")
that failed to hide or remove it from struct task_struct when it was no longer
relevant.
The 0-day kbuildbot was happy and it tests many configs.
On further digging, loginuid and sessionid (and audit_log_session_info) should
be part of CONFIG_AUDIT scope and not CONFIG_AUDITSYSCALL since it is used in
CONFIG_CHANGE, ANOM_LINK, FEATURE_CHANGE(, INTEGRITY_RULE), none of which are
otherwise dependent on AUDITSYSCALL.
Looking ahead, contid should be treated like loginuid and sessionid, which are
currently only available when syscall auditting is.
Converting records from standalone to syscall and checking audit_dummy_context
changes the nature of CONFIG_AUDIT/!CONFIG_AUDITSYSCALL separation.
eg: ANOM_LINK accompanied by PATH record (which needed CWD addition to be
complete anyways)
It seems like we would need either init_struct_audit or
audit_task_init(), but not both, yes?
One sets initial values of init task via an included struct, other makes a call
to create the kmem cache. Both seem appropriate to me unless we move the
initialization from a struct to assignments in audit_task_init(), but I'm not
that comfortable separating the audit init values from the rest of the
task_struct init task initializers (though there are other subsystems that need
to do so dynamically).
This is somewhat related to the CONFIG_AUDITSYSCALL comment above, but
since the audit_task_info contains generic audit state (not just
syscall related state), it seems like this, and the audit_task_info
accessors/helpers, should live in kernel/audit.c.
Well, in fact it was only containing syscall related state.
There are probably a few other things that should move to
kernel/audit.c too, e.g. audit_alloc(). Have you verified that this
builds/runs correctly on architectures that define CONFIG_AUDIT but
not CONFIG_AUDITSYSCALL?
I was under the mistaken impression that all this went away and wondered why
not just rip out the AUDITSYSCALL config option, but that was not completely
solved by cb74ed278f80 ("audit: always enable syscall auditing when supported
and audit is enabled").
I vaguely knew that AUDITSYSCALL was not implemented on all platforms but that
a number were expunged recently from mainline. It turns out that 5-10+ remain.
quoted
/**
* audit_alloc - allocate an audit context block for a task
* @tsk: task
@@ -940,17 +949,28 @@ int audit_alloc(struct task_struct *tsk) struct audit_context *context; enum audit_state state; char *key = NULL;+ struct audit_task_info *info;++ info = kmem_cache_zalloc(audit_task_cache, GFP_KERNEL);+ if (!info)+ return -ENOMEM;+ info->loginuid = audit_get_loginuid(current);+ info->sessionid = audit_get_sessionid(current);+ tsk->audit = info; if (likely(!audit_ever_enabled)) return 0; /* Return if not auditing. */
I don't view this as necessary for initial acceptance, and
synchronization/locking might render this undesirable, but it would be
curious to see if we could do something clever with refcnts and
copy-on-write to minimize the number of kmem_cache objects in use in
the !audit_ever_enabled (and possibly the AUDIT_DISABLED) case.
quoted
state = audit_filter_task(tsk, &key);
if (state == AUDIT_DISABLED) {
+ audit_set_context(tsk, NULL);
It's already NULL, isn't it?
Yes, holdover from copying audit_task_info as a struct from the parent task.
Fixed.
quoted
clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
return 0;
}
if (!(context = audit_alloc_context(state))) {
+ tsk->audit = NULL;
+ kmem_cache_free(audit_task_cache, info);
kfree(key);
audit_log_lost("out of memory in audit_alloc");
return -ENOMEM;
- 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,
On Tue, Jul 31, 2018 at 04:07:35PM -0400, Richard Guy Briggs wrote:
Implement kernel audit container identifier.
I don't see a follow-up submission of this patch series. Has it been abandoned,
or do I use the wrong search terms ?
Thanks,
Guenter
This patchset is a fourth based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch is the last patch from ghak81 that is included here as a
convenience.
The second patch implements the proc fs write to set the audit container
identifier of a process, emitting an AUDIT_CONTAINER_OP record to announce the
registration of that audit container identifier on that process. This patch
requires userspace support for record acceptance and proper type
display.
The third implements the auxiliary record AUDIT_CONTAINER if an
audit container identifier is identifiable with an event. This patch
requires userspace support for proper type display.
The 4th adds signal and ptrace support.
The 5th creates a local audit context to be able to bind a standalone
record with a locally created auxiliary record.
The 6th patch adds audit container identifier records to the tty
standalone record.
The 7th adds audit container identifier filtering to the exit,
exclude and user lists. This patch adds the AUDIT_CONTID field and
requires auditctl userspace support for the --contid option.
The 8th adds network namespace audit container identifier labelling
based on member tasks' audit container identifier labels.
The 9th adds audit container identifier support to standalone netfilter
records that don't have a task context and lists each container to which
that net namespace belongs.
The 10th implements reading the audit container identifier from the proc
filesystem for debugging. This patch isn't planned for upstream
inclusion.
Example: Set an audit container identifier of 123456 to the "sleep" task:
sleep 2&
child=$!
echo 123456 > /proc/$child/audit_containerid; echo $?
ausearch -ts recent -m container
echo child:$child contid:$( cat /proc/$child/audit_containerid)
This should produce a record such as:
type=CONTAINER_OP 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
Example: Set a filter on an audit container identifier 123459 on /tmp/tmpcontainerid:
contid=123459
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
perl -e "sleep 1; open(my \$tmpfile, '>', \"/tmp/$key\"); close(\$tmpfile);" &
child=$!
echo $contid > /proc/$child/audit_containerid
sleep 2
ausearch -i -ts recent -k $key
auditctl -d exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
rm -f /tmp/$key
This should produce an event such as:
type=CONTAINER msg=audit(2018-06-06 12:46:31.707:26953) : op=task contid=123459
type=PROCTITLE msg=audit(2018-06-06 12:46:31.707:26953) : proctitle=perl -e sleep 1; open(my $tmpfile, '>', "/tmp/tmpcontainerid"); close($tmpfile);
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=1 name=/tmp/tmpcontainerid inode=25656 dev=00:26 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=0 name=/tmp/ inode=8985 dev=00:26 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=CWD msg=audit(2018-06-06 12:46:31.707:26953) : cwd=/root
type=SYSCALL msg=audit(2018-06-06 12:46:31.707:26953) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffffffffffff9c a1=0x5621f2b81900 a2=O_WRONLY|O_CREAT|O_TRUNC a3=0x1b6 items=2 ppid=628 pid=2232 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=ttyS0 ses=1 comm=perl exe=/usr/bin/perl subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=tmpcontainerid
Includes: https://github.com/linux-audit/audit-kernel/issues/81
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Changelog:
v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(&tasklist_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless
v3
- switched from containerid in task_struct to audit_task_info (depends on ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name collision
v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid
Richard Guy Briggs (10):
audit: collect audit task parameters
audit: add container id
audit: log container info of syscalls
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add containerid support for tty_audit
audit: add containerid filtering
audit: add support for containerid to network namespaces
audit: NETFILTER_PKT: record each container ID associated with a netNS
debug audit: read container ID of a process
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 56 ++++++++++++++
include/linux/audit.h | 95 ++++++++++++++++++++---
include/linux/sched.h | 5 +-
include/uapi/linux/audit.h | 8 +-
init/init_task.c | 3 +-
init/main.c | 2 +
kernel/audit.c | 137 +++++++++++++++++++++++++++++++++
kernel/audit.h | 4 +
kernel/auditfilter.c | 47 ++++++++++++
kernel/auditsc.c | 183 ++++++++++++++++++++++++++++++++++++++++-----
kernel/fork.c | 4 +-
kernel/nsproxy.c | 4 +
net/netfilter/xt_AUDIT.c | 12 ++-
14 files changed, 526 insertions(+), 39 deletions(-)
--
1.8.3.1
From: Richard Guy Briggs <hidden> Date: 2019-01-03 17:36:29
On 2019-01-03 08:15, Guenter Roeck wrote:
Hi,
On Tue, Jul 31, 2018 at 04:07:35PM -0400, Richard Guy Briggs wrote:
quoted
Implement kernel audit container identifier.
I don't see a follow-up submission of this patch series. Has it been abandoned,
or do I use the wrong search terms ?
Guenter, thanks for your interest in this patchset. I haven't
abandoned it. I've pushed some updates to my own (ill-publicized)
public git repo. This effort has been going on more than 5 years with 8
previous revisions trying to document task namespaces and deciding that
was insufficient.
For this patchset I waited 11.5 weeks (80 days, Jules Verne anyone?)
before the primary intended maintainer did the first review, then I
responded within 2 weeks with further questions and a followup patch
proposal and then waited another 8 weeks for any response before adding
another query for that followup patch proposal review at which point I
got a rude answer saying I had disappointed and exhausted the
maintainer's goodwill with some hints at how to proceed just before new
year's.
I'd be delighted with other upstream review to get other angles and to
take some of the load and responsibility off the primary maintainer.
I expect to submit a v5 within a week without having had those questions
directly answered, but with some ideas of what to check and verify
before I resubmit. Most of the changes have been sitting in that branch
for two months, already rebased one kernel version and will need
updating again.
Thanks,
Guenter
quoted
This patchset is a fourth based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch is the last patch from ghak81 that is included here as a
convenience.
The second patch implements the proc fs write to set the audit container
identifier of a process, emitting an AUDIT_CONTAINER_OP record to announce the
registration of that audit container identifier on that process. This patch
requires userspace support for record acceptance and proper type
display.
The third implements the auxiliary record AUDIT_CONTAINER if an
audit container identifier is identifiable with an event. This patch
requires userspace support for proper type display.
The 4th adds signal and ptrace support.
The 5th creates a local audit context to be able to bind a standalone
record with a locally created auxiliary record.
The 6th patch adds audit container identifier records to the tty
standalone record.
The 7th adds audit container identifier filtering to the exit,
exclude and user lists. This patch adds the AUDIT_CONTID field and
requires auditctl userspace support for the --contid option.
The 8th adds network namespace audit container identifier labelling
based on member tasks' audit container identifier labels.
The 9th adds audit container identifier support to standalone netfilter
records that don't have a task context and lists each container to which
that net namespace belongs.
The 10th implements reading the audit container identifier from the proc
filesystem for debugging. This patch isn't planned for upstream
inclusion.
Example: Set an audit container identifier of 123456 to the "sleep" task:
sleep 2&
child=$!
echo 123456 > /proc/$child/audit_containerid; echo $?
ausearch -ts recent -m container
echo child:$child contid:$( cat /proc/$child/audit_containerid)
This should produce a record such as:
type=CONTAINER_OP 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
Example: Set a filter on an audit container identifier 123459 on /tmp/tmpcontainerid:
contid=123459
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
perl -e "sleep 1; open(my \$tmpfile, '>', \"/tmp/$key\"); close(\$tmpfile);" &
child=$!
echo $contid > /proc/$child/audit_containerid
sleep 2
ausearch -i -ts recent -k $key
auditctl -d exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
rm -f /tmp/$key
This should produce an event such as:
type=CONTAINER msg=audit(2018-06-06 12:46:31.707:26953) : op=task contid=123459
type=PROCTITLE msg=audit(2018-06-06 12:46:31.707:26953) : proctitle=perl -e sleep 1; open(my $tmpfile, '>', "/tmp/tmpcontainerid"); close($tmpfile);
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=1 name=/tmp/tmpcontainerid inode=25656 dev=00:26 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=0 name=/tmp/ inode=8985 dev=00:26 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=CWD msg=audit(2018-06-06 12:46:31.707:26953) : cwd=/root
type=SYSCALL msg=audit(2018-06-06 12:46:31.707:26953) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffffffffffff9c a1=0x5621f2b81900 a2=O_WRONLY|O_CREAT|O_TRUNC a3=0x1b6 items=2 ppid=628 pid=2232 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=ttyS0 ses=1 comm=perl exe=/usr/bin/perl subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=tmpcontainerid
Includes: https://github.com/linux-audit/audit-kernel/issues/81
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Changelog:
v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(&tasklist_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless
v3
- switched from containerid in task_struct to audit_task_info (depends on ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name collision
v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid
Richard Guy Briggs (10):
audit: collect audit task parameters
audit: add container id
audit: log container info of syscalls
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add containerid support for tty_audit
audit: add containerid filtering
audit: add support for containerid to network namespaces
audit: NETFILTER_PKT: record each container ID associated with a netNS
debug audit: read container ID of a process
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 56 ++++++++++++++
include/linux/audit.h | 95 ++++++++++++++++++++---
include/linux/sched.h | 5 +-
include/uapi/linux/audit.h | 8 +-
init/init_task.c | 3 +-
init/main.c | 2 +
kernel/audit.c | 137 +++++++++++++++++++++++++++++++++
kernel/audit.h | 4 +
kernel/auditfilter.c | 47 ++++++++++++
kernel/auditsc.c | 183 ++++++++++++++++++++++++++++++++++++++++-----
kernel/fork.c | 4 +-
kernel/nsproxy.c | 4 +
net/netfilter/xt_AUDIT.c | 12 ++-
14 files changed, 526 insertions(+), 39 deletions(-)
--
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
Hi Richard,
On Thu, Jan 03, 2019 at 12:36:13PM -0500, Richard Guy Briggs wrote:
On 2019-01-03 08:15, Guenter Roeck wrote:
quoted
Hi,
On Tue, Jul 31, 2018 at 04:07:35PM -0400, Richard Guy Briggs wrote:
quoted
Implement kernel audit container identifier.
I don't see a follow-up submission of this patch series. Has it been abandoned,
or do I use the wrong search terms ?
Guenter, thanks for your interest in this patchset. I haven't
abandoned it. I've pushed some updates to my own (ill-publicized)
public git repo. This effort has been going on more than 5 years with 8
Oh man :-(. Not sure if I would be that patient.
Can you point me to your repository ?
previous revisions trying to document task namespaces and deciding that
was insufficient.
My interest is mostly thanks to having some of the patches of your series
in my incoming code review queue:
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1379654/3
As background, some of the patches in the series are needed by GCP (Google
Cloud Platform) as a prerequisite for some security features. Having to
maintain out-of-tree code is always a pain, even more so in a subsystem
related to security. So it would be quite useful to understand if we are
going to be stuck with this forever or if there is a change for the code
to find its way upstream. Also, it would be useful to know if there are
some upcoming changes/improvements which should be included in our version.
Thanks,
Guenter
For this patchset I waited 11.5 weeks (80 days, Jules Verne anyone?)
before the primary intended maintainer did the first review, then I
responded within 2 weeks with further questions and a followup patch
proposal and then waited another 8 weeks for any response before adding
another query for that followup patch proposal review at which point I
got a rude answer saying I had disappointed and exhausted the
maintainer's goodwill with some hints at how to proceed just before new
year's.
I'd be delighted with other upstream review to get other angles and to
take some of the load and responsibility off the primary maintainer.
I expect to submit a v5 within a week without having had those questions
directly answered, but with some ideas of what to check and verify
before I resubmit. Most of the changes have been sitting in that branch
for two months, already rebased one kernel version and will need
updating again.
quoted
Thanks,
Guenter
quoted
This patchset is a fourth based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch is the last patch from ghak81 that is included here as a
convenience.
The second patch implements the proc fs write to set the audit container
identifier of a process, emitting an AUDIT_CONTAINER_OP record to announce the
registration of that audit container identifier on that process. This patch
requires userspace support for record acceptance and proper type
display.
The third implements the auxiliary record AUDIT_CONTAINER if an
audit container identifier is identifiable with an event. This patch
requires userspace support for proper type display.
The 4th adds signal and ptrace support.
The 5th creates a local audit context to be able to bind a standalone
record with a locally created auxiliary record.
The 6th patch adds audit container identifier records to the tty
standalone record.
The 7th adds audit container identifier filtering to the exit,
exclude and user lists. This patch adds the AUDIT_CONTID field and
requires auditctl userspace support for the --contid option.
The 8th adds network namespace audit container identifier labelling
based on member tasks' audit container identifier labels.
The 9th adds audit container identifier support to standalone netfilter
records that don't have a task context and lists each container to which
that net namespace belongs.
The 10th implements reading the audit container identifier from the proc
filesystem for debugging. This patch isn't planned for upstream
inclusion.
Example: Set an audit container identifier of 123456 to the "sleep" task:
sleep 2&
child=$!
echo 123456 > /proc/$child/audit_containerid; echo $?
ausearch -ts recent -m container
echo child:$child contid:$( cat /proc/$child/audit_containerid)
This should produce a record such as:
type=CONTAINER_OP 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
Example: Set a filter on an audit container identifier 123459 on /tmp/tmpcontainerid:
contid=123459
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
perl -e "sleep 1; open(my \$tmpfile, '>', \"/tmp/$key\"); close(\$tmpfile);" &
child=$!
echo $contid > /proc/$child/audit_containerid
sleep 2
ausearch -i -ts recent -k $key
auditctl -d exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
rm -f /tmp/$key
This should produce an event such as:
type=CONTAINER msg=audit(2018-06-06 12:46:31.707:26953) : op=task contid=123459
type=PROCTITLE msg=audit(2018-06-06 12:46:31.707:26953) : proctitle=perl -e sleep 1; open(my $tmpfile, '>', "/tmp/tmpcontainerid"); close($tmpfile);
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=1 name=/tmp/tmpcontainerid inode=25656 dev=00:26 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=0 name=/tmp/ inode=8985 dev=00:26 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=CWD msg=audit(2018-06-06 12:46:31.707:26953) : cwd=/root
type=SYSCALL msg=audit(2018-06-06 12:46:31.707:26953) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffffffffffff9c a1=0x5621f2b81900 a2=O_WRONLY|O_CREAT|O_TRUNC a3=0x1b6 items=2 ppid=628 pid=2232 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=ttyS0 ses=1 comm=perl exe=/usr/bin/perl subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=tmpcontainerid
Includes: https://github.com/linux-audit/audit-kernel/issues/81
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Changelog:
v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(&tasklist_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless
v3
- switched from containerid in task_struct to audit_task_info (depends on ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name collision
v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid
Richard Guy Briggs (10):
audit: collect audit task parameters
audit: add container id
audit: log container info of syscalls
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add containerid support for tty_audit
audit: add containerid filtering
audit: add support for containerid to network namespaces
audit: NETFILTER_PKT: record each container ID associated with a netNS
debug audit: read container ID of a process
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 56 ++++++++++++++
include/linux/audit.h | 95 ++++++++++++++++++++---
include/linux/sched.h | 5 +-
include/uapi/linux/audit.h | 8 +-
init/init_task.c | 3 +-
init/main.c | 2 +
kernel/audit.c | 137 +++++++++++++++++++++++++++++++++
kernel/audit.h | 4 +
kernel/auditfilter.c | 47 ++++++++++++
kernel/auditsc.c | 183 ++++++++++++++++++++++++++++++++++++++++-----
kernel/fork.c | 4 +-
kernel/nsproxy.c | 4 +
net/netfilter/xt_AUDIT.c | 12 ++-
14 files changed, 526 insertions(+), 39 deletions(-)
--
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: 2019-01-03 20:10:47
On Thu, Nov 1, 2018 at 6:07 PM Richard Guy Briggs [off-list ref] wrote:
> On 2018-10-19 19:15, Paul Moore wrote:
> > On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
> > > The audit-related parameters in struct task_struct
should ideally be
> > > collected together and accessed through a standard audit API.
> > >
> > > Collect the existing loginuid, sessionid and
audit_context together in a
> > > new struct audit_task_info called "audit" in struct task_struct.
> > >
> > > Use kmem_cache to manage this pool of memory.
> > > Un-inline audit_free() to be able to always recover that memory.
> > >
> > > See: https://github.com/linux-audit/audit-kernel/issues/81
> > >
> > > Signed-off-by: Richard Guy Briggs [off-list ref]
> > > ---
> > > include/linux/audit.h | 34 ++++++++++++++++++++++++----------
> > > include/linux/sched.h | 5 +----
> > > init/init_task.c | 3 +--
> > > init/main.c | 2 ++
> > > kernel/auditsc.c | 51
++++++++++++++++++++++++++++++++++++++++++---------
> > > kernel/fork.c | 4 +++-
> > > 6 files changed, 73 insertions(+), 26 deletions(-)
> >
> > ...
> >
> > > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > > index 87bf02d..e117272 100644
> > > --- a/include/linux/sched.h
> > > +++ b/include/linux/sched.h
> > > @@ -873,10 +872,8 @@ struct task_struct {
> > >
> > > struct callback_head *task_works;
> > >
> > > - struct audit_context *audit_context;
> > > #ifdef CONFIG_AUDITSYSCALL
> > > - kuid_t loginuid;
> > > - unsigned int sessionid;
> > > + struct audit_task_info *audit;
> > > #endif
> > > struct seccomp seccomp;
> >
> > Prior to this patch audit_context was available regardless of
> > CONFIG_AUDITSYSCALL, after this patch the corresponding audit_context
> > is only available when CONFIG_AUDITSYSCALL is defined.
>
> This was intentional since audit_context is not used when AUDITSYSCALL is
> disabled. audit_alloc() was stubbed in that case to return 0.
audit_context()
> returned NULL.
>
> The fact that audit_context was still present in struct task_struct was an
> oversight in the two patches already accepted:
> ("audit: use inline function to get audit context")
> ("audit: use inline function to get audit context")
> that failed to hide or remove it from struct task_struct when it
was no longer
> relevant.
Okay, in that case let's pull this out and fix this separately from
the audit container ID patchset.
> On further digging, loginuid and sessionid (and
audit_log_session_info) should
> be part of CONFIG_AUDIT scope and not CONFIG_AUDITSYSCALL since
it is used in
> CONFIG_CHANGE, ANOM_LINK, FEATURE_CHANGE(, INTEGRITY_RULE), none
of which are
> otherwise dependent on AUDITSYSCALL.
This looks like something else we should fix independently from this patchset.
> Looking ahead, contid should be treated like loginuid and
sessionid, which are
> currently only available when syscall auditting is.
That seems reasonable. Eventually it would be great if we got rid of
CONFIG_AUDITSYSCALL, but that is a separate issue, and something that
is going to require work from the different arch/ABI folks to ensure
everything is working properly.
> Converting records from standalone to syscall and checking
audit_dummy_context
> changes the nature of CONFIG_AUDIT/!CONFIG_AUDITSYSCALL separation.
> eg: ANOM_LINK accompanied by PATH record (which needed CWD addition to be
> complete anyways)
>
> > > diff --git a/init/main.c b/init/main.c
> > > index 3b4ada1..6aba171 100644
> > > --- a/init/main.c
> > > +++ b/init/main.c
> > > @@ -92,6 +92,7 @@
> > > #include <linux rodata_test.h="">
> > > #include <linux jump_label.h="">
> > > #include <linux mem_encrypt.h="">
> > > +#include <linux audit.h="">
> > >
> > > #include <asm io.h="">
> > > #include <asm bugs.h="">
> > > @@ -721,6 +722,7 @@ asmlinkage __visible void __init
start_kernel(void)
> > > nsfs_init();
> > > cpuset_init();
> > > cgroup_init();
> > > + audit_task_init();
> > > taskstats_init_early();
> > > delayacct_init();
> >
> > It seems like we would need either init_struct_audit or
> > audit_task_init(), but not both, yes?
>
> One sets initial values of init task via an included struct,
other makes a call
> to create the kmem cache. Both seem appropriate to me unless we move the
> initialization from a struct to assignments in audit_task_init(),
but I'm not
> that comfortable separating the audit init values from the rest of the
> task_struct init task initializers (though there are other
subsystems that need
> to do so dynamically).
My original thinking was focused on the use of init_struct_audit as an
initializer when audit_task_init() was already creating a kmem_cache
pool and a zero'd/init'd audit_task_info could be obtained via the
usual kmem_cache functions. Alternatively, although I don't believe
it would be recommended for this case, would be to use
init_struct_audit as an init helper if we included the audit_task_info
struct directly in the task_struct, as opposed to a pointer. What I
missed was the simple fact that you're only using init_struct_audit
for the init_task, which pretty much makes my original question rather
silly :)
--
paul moore
www.paul-moore.com
From: Paul Moore <paul@paul-moore.com> Date: 2019-01-03 20:12:40
On Thu, Jan 3, 2019 at 12:36 PM Richard Guy Briggs [off-list ref] wrote:
On 2019-01-03 08:15, Guenter Roeck wrote:
quoted
Hi,
On Tue, Jul 31, 2018 at 04:07:35PM -0400, Richard Guy Briggs wrote:
quoted
Implement kernel audit container identifier.
I don't see a follow-up submission of this patch series. Has it been abandoned,
or do I use the wrong search terms ?
Guenter, thanks for your interest in this patchset. I haven't
abandoned it. I've pushed some updates to my own (ill-publicized)
public git repo. This effort has been going on more than 5 years with 8
previous revisions trying to document task namespaces and deciding that
was insufficient.
For this patchset I waited 11.5 weeks (80 days, Jules Verne anyone?)
before the primary intended maintainer did the first review, then I
responded within 2 weeks with further questions and a followup patch
proposal and then waited another 8 weeks for any response before adding
another query for that followup patch proposal review at which point I
got a rude answer saying I had disappointed and exhausted the
maintainer's goodwill with some hints at how to proceed just before new
year's.
For what it is worth, I've found your emails to me to be rather "rude"
as well (to borrow the term), and I responded with what I felt was
appropriate. Perhaps our interactions may have been seen as overly,
or quickly, harsh but I would remind those that we have several years
of history that extends far beyond the lists which obviously affects
how we interact. Our expectations for each other are clearly higher
than either of us are delivering, so I'm going to suggest what I've
suggested before, albeit privately: let's stick to the code, that's
where we can find common ground.
There were only a few outstanding threads/questions from your last
posting, you should have responses to those sitting in your inbox now.
I'd be delighted with other upstream review to get other angles and to
take some of the load and responsibility off the primary maintainer.
I expect to submit a v5 within a week without having had those questions
directly answered, but with some ideas of what to check and verify
before I resubmit. Most of the changes have been sitting in that branch
for two months, already rebased one kernel version and will need
updating again.
From: Richard Guy Briggs <hidden> Date: 2019-01-03 20:21:07
On 2019-01-03 10:58, Guenter Roeck wrote:
Hi Richard,
On Thu, Jan 03, 2019 at 12:36:13PM -0500, Richard Guy Briggs wrote:
quoted
On 2019-01-03 08:15, Guenter Roeck wrote:
quoted
Hi,
On Tue, Jul 31, 2018 at 04:07:35PM -0400, Richard Guy Briggs wrote:
quoted
Implement kernel audit container identifier.
I don't see a follow-up submission of this patch series. Has it been abandoned,
or do I use the wrong search terms ?
Guenter, thanks for your interest in this patchset. I haven't
abandoned it. I've pushed some updates to my own (ill-publicized)
public git repo. This effort has been going on more than 5 years with 8
Oh man :-(. Not sure if I would be that patient.
Patience, subbornness, unjustified optimism, tenacity, inflexibility, who knows...
Are you talking about sticking with this particular problem, or delay
before checking in on a particular patch review?
Can you point me to your repository ?
Sure. It hasn't been squashed and will be rebased.
git://toccata2.tricolour.ca/linux-2.6-rgb.git
I still have some write locks to check and work on.
quoted
previous revisions trying to document task namespaces and deciding that
was insufficient.
Ok, interesting. Michael Halcrow had approached me in Vancouver at LSS
at the end of August and I regret not having had enough time to talk
with him further about it.
As background, some of the patches in the series are needed by GCP (Google
Cloud Platform) as a prerequisite for some security features. Having to
maintain out-of-tree code is always a pain, even more so in a subsystem
related to security. So it would be quite useful to understand if we are
going to be stuck with this forever or if there is a change for the code
to find its way upstream. Also, it would be useful to know if there are
some upcoming changes/improvements which should be included in our version.
There are likely more changes coming, but I don't expect them to be
that drastic a departure from the original design. There were some
changes in the implementation based on unforseen issues raised once
coding started (which is part of the process). Upstream patch review
would be the most helpful in keeping this stuff moving.
David Howells also had some interesting ideas and patches to try to
address some of these problems and he's still working on a prerequisite
patchset to get it upstream before returning to his container identifier
patchset. It is moving slowly.
Thanks,
Guenter
quoted
For this patchset I waited 11.5 weeks (80 days, Jules Verne anyone?)
before the primary intended maintainer did the first review, then I
responded within 2 weeks with further questions and a followup patch
proposal and then waited another 8 weeks for any response before adding
another query for that followup patch proposal review at which point I
got a rude answer saying I had disappointed and exhausted the
maintainer's goodwill with some hints at how to proceed just before new
year's.
I'd be delighted with other upstream review to get other angles and to
take some of the load and responsibility off the primary maintainer.
I expect to submit a v5 within a week without having had those questions
directly answered, but with some ideas of what to check and verify
before I resubmit. Most of the changes have been sitting in that branch
for two months, already rebased one kernel version and will need
updating again.
quoted
Thanks,
Guenter
quoted
This patchset is a fourth based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch is the last patch from ghak81 that is included here as a
convenience.
The second patch implements the proc fs write to set the audit container
identifier of a process, emitting an AUDIT_CONTAINER_OP record to announce the
registration of that audit container identifier on that process. This patch
requires userspace support for record acceptance and proper type
display.
The third implements the auxiliary record AUDIT_CONTAINER if an
audit container identifier is identifiable with an event. This patch
requires userspace support for proper type display.
The 4th adds signal and ptrace support.
The 5th creates a local audit context to be able to bind a standalone
record with a locally created auxiliary record.
The 6th patch adds audit container identifier records to the tty
standalone record.
The 7th adds audit container identifier filtering to the exit,
exclude and user lists. This patch adds the AUDIT_CONTID field and
requires auditctl userspace support for the --contid option.
The 8th adds network namespace audit container identifier labelling
based on member tasks' audit container identifier labels.
The 9th adds audit container identifier support to standalone netfilter
records that don't have a task context and lists each container to which
that net namespace belongs.
The 10th implements reading the audit container identifier from the proc
filesystem for debugging. This patch isn't planned for upstream
inclusion.
Example: Set an audit container identifier of 123456 to the "sleep" task:
sleep 2&
child=$!
echo 123456 > /proc/$child/audit_containerid; echo $?
ausearch -ts recent -m container
echo child:$child contid:$( cat /proc/$child/audit_containerid)
This should produce a record such as:
type=CONTAINER_OP 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
Example: Set a filter on an audit container identifier 123459 on /tmp/tmpcontainerid:
contid=123459
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
perl -e "sleep 1; open(my \$tmpfile, '>', \"/tmp/$key\"); close(\$tmpfile);" &
child=$!
echo $contid > /proc/$child/audit_containerid
sleep 2
ausearch -i -ts recent -k $key
auditctl -d exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
rm -f /tmp/$key
This should produce an event such as:
type=CONTAINER msg=audit(2018-06-06 12:46:31.707:26953) : op=task contid=123459
type=PROCTITLE msg=audit(2018-06-06 12:46:31.707:26953) : proctitle=perl -e sleep 1; open(my $tmpfile, '>', "/tmp/tmpcontainerid"); close($tmpfile);
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=1 name=/tmp/tmpcontainerid inode=25656 dev=00:26 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=0 name=/tmp/ inode=8985 dev=00:26 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=CWD msg=audit(2018-06-06 12:46:31.707:26953) : cwd=/root
type=SYSCALL msg=audit(2018-06-06 12:46:31.707:26953) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffffffffffff9c a1=0x5621f2b81900 a2=O_WRONLY|O_CREAT|O_TRUNC a3=0x1b6 items=2 ppid=628 pid=2232 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=ttyS0 ses=1 comm=perl exe=/usr/bin/perl subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=tmpcontainerid
Includes: https://github.com/linux-audit/audit-kernel/issues/81
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Changelog:
v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(&tasklist_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless
v3
- switched from containerid in task_struct to audit_task_info (depends on ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name collision
v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid
Richard Guy Briggs (10):
audit: collect audit task parameters
audit: add container id
audit: log container info of syscalls
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add containerid support for tty_audit
audit: add containerid filtering
audit: add support for containerid to network namespaces
audit: NETFILTER_PKT: record each container ID associated with a netNS
debug audit: read container ID of a process
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 56 ++++++++++++++
include/linux/audit.h | 95 ++++++++++++++++++++---
include/linux/sched.h | 5 +-
include/uapi/linux/audit.h | 8 +-
init/init_task.c | 3 +-
init/main.c | 2 +
kernel/audit.c | 137 +++++++++++++++++++++++++++++++++
kernel/audit.h | 4 +
kernel/auditfilter.c | 47 ++++++++++++
kernel/auditsc.c | 183 ++++++++++++++++++++++++++++++++++++++++-----
kernel/fork.c | 4 +-
kernel/nsproxy.c | 4 +
net/netfilter/xt_AUDIT.c | 12 ++-
14 files changed, 526 insertions(+), 39 deletions(-)
--
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
- 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: Richard Guy Briggs <hidden> Date: 2019-01-03 20:29:53
I'm not sure what's going on here, but it looks like HTML-encoded reply
quoting making the quoted text very difficult to read. All the previous
">" have been converted to the HTML ">" encoding. Your most recent
reply text looks mostly fine.
On 2019-01-03 15:10, Paul Moore wrote:
On Thu, Nov 1, 2018 at 6:07 PM Richard Guy Briggs [off-list ref] wrote:
> On 2018-10-19 19:15, Paul Moore wrote:
> > On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
> > > The audit-related parameters in struct task_struct
should ideally be
> > > collected together and accessed through a standard audit API.
> > >
> > > Collect the existing loginuid, sessionid and
audit_context together in a
> > > new struct audit_task_info called "audit" in struct task_struct.
> > >
> > > Use kmem_cache to manage this pool of memory.
> > > Un-inline audit_free() to be able to always recover that memory.
> > >
> > > See: https://github.com/linux-audit/audit-kernel/issues/81
> > >
> > > Signed-off-by: Richard Guy Briggs [off-list ref]
> > > ---
> > > include/linux/audit.h | 34 ++++++++++++++++++++++++----------
> > > include/linux/sched.h | 5 +----
> > > init/init_task.c | 3 +--
> > > init/main.c | 2 ++
> > > kernel/auditsc.c | 51
++++++++++++++++++++++++++++++++++++++++++---------
> > > kernel/fork.c | 4 +++-
> > > 6 files changed, 73 insertions(+), 26 deletions(-)
> >
> > ...
> >
> > > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > > index 87bf02d..e117272 100644
> > > --- a/include/linux/sched.h
> > > +++ b/include/linux/sched.h
> > > @@ -873,10 +872,8 @@ struct task_struct {
> > >
> > > struct callback_head *task_works;
> > >
> > > - struct audit_context *audit_context;
> > > #ifdef CONFIG_AUDITSYSCALL
> > > - kuid_t loginuid;
> > > - unsigned int sessionid;
> > > + struct audit_task_info *audit;
> > > #endif
> > > struct seccomp seccomp;
> >
> > Prior to this patch audit_context was available regardless of
> > CONFIG_AUDITSYSCALL, after this patch the corresponding audit_context
> > is only available when CONFIG_AUDITSYSCALL is defined.
>
> This was intentional since audit_context is not used when AUDITSYSCALL is
> disabled. audit_alloc() was stubbed in that case to return 0.
audit_context()
> returned NULL.
>
> The fact that audit_context was still present in struct task_struct was an
> oversight in the two patches already accepted:
> ("audit: use inline function to get audit context")
> ("audit: use inline function to get audit context")
> that failed to hide or remove it from struct task_struct when it
was no longer
> relevant.
Okay, in that case let's pull this out and fix this separately from
the audit container ID patchset.
> On further digging, loginuid and sessionid (and
audit_log_session_info) should
> be part of CONFIG_AUDIT scope and not CONFIG_AUDITSYSCALL since
it is used in
> CONFIG_CHANGE, ANOM_LINK, FEATURE_CHANGE(, INTEGRITY_RULE), none
of which are
> otherwise dependent on AUDITSYSCALL.
This looks like something else we should fix independently from this patchset.
> Looking ahead, contid should be treated like loginuid and
sessionid, which are
> currently only available when syscall auditting is.
That seems reasonable. Eventually it would be great if we got rid of
CONFIG_AUDITSYSCALL, but that is a separate issue, and something that
is going to require work from the different arch/ABI folks to ensure
everything is working properly.
> Converting records from standalone to syscall and checking
audit_dummy_context
> changes the nature of CONFIG_AUDIT/!CONFIG_AUDITSYSCALL separation.
> eg: ANOM_LINK accompanied by PATH record (which needed CWD addition to be
> complete anyways)
>
> > > diff --git a/init/main.c b/init/main.c
> > > index 3b4ada1..6aba171 100644
> > > --- a/init/main.c
> > > +++ b/init/main.c
> > > @@ -92,6 +92,7 @@
> > > #include <linux rodata_test.h="">
> > > #include <linux jump_label.h="">
> > > #include <linux mem_encrypt.h="">
> > > +#include <linux audit.h="">
> > >
> > > #include <asm io.h="">
> > > #include <asm bugs.h="">
> > > @@ -721,6 +722,7 @@ asmlinkage __visible void __init
start_kernel(void)
> > > nsfs_init();
> > > cpuset_init();
> > > cgroup_init();
> > > + audit_task_init();
> > > taskstats_init_early();
> > > delayacct_init();
> >
> > It seems like we would need either init_struct_audit or
> > audit_task_init(), but not both, yes?
>
> One sets initial values of init task via an included struct,
other makes a call
> to create the kmem cache. Both seem appropriate to me unless we move the
> initialization from a struct to assignments in audit_task_init(),
but I'm not
> that comfortable separating the audit init values from the rest of the
> task_struct init task initializers (though there are other
subsystems that need
> to do so dynamically).
My original thinking was focused on the use of init_struct_audit as an
initializer when audit_task_init() was already creating a kmem_cache
pool and a zero'd/init'd audit_task_info could be obtained via the
usual kmem_cache functions. Alternatively, although I don't believe
it would be recommended for this case, would be to use
init_struct_audit as an init helper if we included the audit_task_info
struct directly in the task_struct, as opposed to a pointer. What I
missed was the simple fact that you're only using init_struct_audit
for the init_task, which pretty much makes my original question rather
silly :)
--
paul moore
www.paul-moore.com
- 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: 2019-01-03 20:33:44
On Thu, Jan 3, 2019 at 3:29 PM Richard Guy Briggs [off-list ref] wrote:
I'm not sure what's going on here, but it looks like HTML-encoded reply
quoting making the quoted text very difficult to read. All the previous
">" have been converted to the HTML ">" encoding. Your most recent
reply text looks mostly fine.
Not sure what happened either, I suspect gmail did something odd when
I saved them as drafts, but it has never done that before. FWIW, I
generally batch up individual review comments for complex patchsets as
one often needs to review the entire set first before commenting.
The most recent reply to patch 0/10 wasn't saved as a draft before sending.
On 2019-01-03 15:10, Paul Moore wrote:
quoted
On Thu, Nov 1, 2018 at 6:07 PM Richard Guy Briggs [off-list ref] wrote:
> On 2018-10-19 19:15, Paul Moore wrote:
> > On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
> > > The audit-related parameters in struct task_struct
should ideally be
> > > collected together and accessed through a standard audit API.
> > >
> > > Collect the existing loginuid, sessionid and
audit_context together in a
> > > new struct audit_task_info called "audit" in struct task_struct.
> > >
> > > Use kmem_cache to manage this pool of memory.
> > > Un-inline audit_free() to be able to always recover that memory.
> > >
> > > See: https://github.com/linux-audit/audit-kernel/issues/81
> > >
> > > Signed-off-by: Richard Guy Briggs [off-list ref]
> > > ---
> > > include/linux/audit.h | 34 ++++++++++++++++++++++++----------
> > > include/linux/sched.h | 5 +----
> > > init/init_task.c | 3 +--
> > > init/main.c | 2 ++
> > > kernel/auditsc.c | 51
++++++++++++++++++++++++++++++++++++++++++---------
> > > kernel/fork.c | 4 +++-
> > > 6 files changed, 73 insertions(+), 26 deletions(-)
> >
> > ...
> >
> > > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > > index 87bf02d..e117272 100644
> > > --- a/include/linux/sched.h
> > > +++ b/include/linux/sched.h
> > > @@ -873,10 +872,8 @@ struct task_struct {
> > >
> > > struct callback_head *task_works;
> > >
> > > - struct audit_context *audit_context;
> > > #ifdef CONFIG_AUDITSYSCALL
> > > - kuid_t loginuid;
> > > - unsigned int sessionid;
> > > + struct audit_task_info *audit;
> > > #endif
> > > struct seccomp seccomp;
> >
> > Prior to this patch audit_context was available regardless of
> > CONFIG_AUDITSYSCALL, after this patch the corresponding audit_context
> > is only available when CONFIG_AUDITSYSCALL is defined.
>
> This was intentional since audit_context is not used when AUDITSYSCALL is
> disabled. audit_alloc() was stubbed in that case to return 0.
audit_context()
> returned NULL.
>
> The fact that audit_context was still present in struct task_struct was an
> oversight in the two patches already accepted:
> ("audit: use inline function to get audit context")
> ("audit: use inline function to get audit context")
> that failed to hide or remove it from struct task_struct when it
was no longer
> relevant.
Okay, in that case let's pull this out and fix this separately from
the audit container ID patchset.
> On further digging, loginuid and sessionid (and
audit_log_session_info) should
> be part of CONFIG_AUDIT scope and not CONFIG_AUDITSYSCALL since
it is used in
> CONFIG_CHANGE, ANOM_LINK, FEATURE_CHANGE(, INTEGRITY_RULE), none
of which are
> otherwise dependent on AUDITSYSCALL.
This looks like something else we should fix independently from this patchset.
> Looking ahead, contid should be treated like loginuid and
sessionid, which are
> currently only available when syscall auditting is.
That seems reasonable. Eventually it would be great if we got rid of
CONFIG_AUDITSYSCALL, but that is a separate issue, and something that
is going to require work from the different arch/ABI folks to ensure
everything is working properly.
> Converting records from standalone to syscall and checking
audit_dummy_context
> changes the nature of CONFIG_AUDIT/!CONFIG_AUDITSYSCALL separation.
> eg: ANOM_LINK accompanied by PATH record (which needed CWD addition to be
> complete anyways)
>
> > > diff --git a/init/main.c b/init/main.c
> > > index 3b4ada1..6aba171 100644
> > > --- a/init/main.c
> > > +++ b/init/main.c
> > > @@ -92,6 +92,7 @@
> > > #include <linux rodata_test.h="">
> > > #include <linux jump_label.h="">
> > > #include <linux mem_encrypt.h="">
> > > +#include <linux audit.h="">
> > >
> > > #include <asm io.h="">
> > > #include <asm bugs.h="">
> > > @@ -721,6 +722,7 @@ asmlinkage __visible void __init
start_kernel(void)
> > > nsfs_init();
> > > cpuset_init();
> > > cgroup_init();
> > > + audit_task_init();
> > > taskstats_init_early();
> > > delayacct_init();
> >
> > It seems like we would need either init_struct_audit or
> > audit_task_init(), but not both, yes?
>
> One sets initial values of init task via an included struct,
other makes a call
> to create the kmem cache. Both seem appropriate to me unless we move the
> initialization from a struct to assignments in audit_task_init(),
but I'm not
> that comfortable separating the audit init values from the rest of the
> task_struct init task initializers (though there are other
subsystems that need
> to do so dynamically).
My original thinking was focused on the use of init_struct_audit as an
initializer when audit_task_init() was already creating a kmem_cache
pool and a zero'd/init'd audit_task_info could be obtained via the
usual kmem_cache functions. Alternatively, although I don't believe
it would be recommended for this case, would be to use
init_struct_audit as an init helper if we included the audit_task_info
struct directly in the task_struct, as opposed to a pointer. What I
missed was the simple fact that you're only using init_struct_audit
for the init_task, which pretty much makes my original question rather
silly :)
--
paul moore
www.paul-moore.com
- 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: Richard Guy Briggs <hidden> Date: 2019-01-03 20:38:40
On 2019-01-03 15:33, Paul Moore wrote:
On Thu, Jan 3, 2019 at 3:29 PM Richard Guy Briggs [off-list ref] wrote:
quoted
I'm not sure what's going on here, but it looks like HTML-encoded reply
quoting making the quoted text very difficult to read. All the previous
">" have been converted to the HTML ">" encoding. Your most recent
reply text looks mostly fine.
Not sure what happened either, I suspect gmail did something odd when
I saved them as drafts, but it has never done that before. FWIW, I
generally batch up individual review comments for complex patchsets as
one often needs to review the entire set first before commenting.
The most recent reply to patch 0/10 wasn't saved as a draft before sending.
Yeah, I noticed the last one was fine and wondered why it was different.
/me <3 mutt...
quoted
On 2019-01-03 15:10, Paul Moore wrote:
quoted
On Thu, Nov 1, 2018 at 6:07 PM Richard Guy Briggs [off-list ref] wrote:
> On 2018-10-19 19:15, Paul Moore wrote:
> > On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs
[off-list ref] wrote:
> > > The audit-related parameters in struct task_struct
should ideally be
> > > collected together and accessed through a standard audit API.
> > >
> > > Collect the existing loginuid, sessionid and
audit_context together in a
> > > new struct audit_task_info called "audit" in struct task_struct.
> > >
> > > Use kmem_cache to manage this pool of memory.
> > > Un-inline audit_free() to be able to always recover that memory.
> > >
> > > See: https://github.com/linux-audit/audit-kernel/issues/81
> > >
> > > Signed-off-by: Richard Guy Briggs [off-list ref]
> > > ---
> > > include/linux/audit.h | 34 ++++++++++++++++++++++++----------
> > > include/linux/sched.h | 5 +----
> > > init/init_task.c | 3 +--
> > > init/main.c | 2 ++
> > > kernel/auditsc.c | 51
++++++++++++++++++++++++++++++++++++++++++---------
> > > kernel/fork.c | 4 +++-
> > > 6 files changed, 73 insertions(+), 26 deletions(-)
> >
> > ...
> >
> > > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > > index 87bf02d..e117272 100644
> > > --- a/include/linux/sched.h
> > > +++ b/include/linux/sched.h
> > > @@ -873,10 +872,8 @@ struct task_struct {
> > >
> > > struct callback_head *task_works;
> > >
> > > - struct audit_context *audit_context;
> > > #ifdef CONFIG_AUDITSYSCALL
> > > - kuid_t loginuid;
> > > - unsigned int sessionid;
> > > + struct audit_task_info *audit;
> > > #endif
> > > struct seccomp seccomp;
> >
> > Prior to this patch audit_context was available regardless of
> > CONFIG_AUDITSYSCALL, after this patch the corresponding audit_context
> > is only available when CONFIG_AUDITSYSCALL is defined.
>
> This was intentional since audit_context is not used when AUDITSYSCALL is
> disabled. audit_alloc() was stubbed in that case to return 0.
audit_context()
> returned NULL.
>
> The fact that audit_context was still present in struct task_struct was an
> oversight in the two patches already accepted:
> ("audit: use inline function to get audit context")
> ("audit: use inline function to get audit context")
> that failed to hide or remove it from struct task_struct when it
was no longer
> relevant.
Okay, in that case let's pull this out and fix this separately from
the audit container ID patchset.
> On further digging, loginuid and sessionid (and
audit_log_session_info) should
> be part of CONFIG_AUDIT scope and not CONFIG_AUDITSYSCALL since
it is used in
> CONFIG_CHANGE, ANOM_LINK, FEATURE_CHANGE(, INTEGRITY_RULE), none
of which are
> otherwise dependent on AUDITSYSCALL.
This looks like something else we should fix independently from this patchset.
> Looking ahead, contid should be treated like loginuid and
sessionid, which are
> currently only available when syscall auditting is.
That seems reasonable. Eventually it would be great if we got rid of
CONFIG_AUDITSYSCALL, but that is a separate issue, and something that
is going to require work from the different arch/ABI folks to ensure
everything is working properly.
> Converting records from standalone to syscall and checking
audit_dummy_context
> changes the nature of CONFIG_AUDIT/!CONFIG_AUDITSYSCALL separation.
> eg: ANOM_LINK accompanied by PATH record (which needed CWD addition to be
> complete anyways)
>
> > > diff --git a/init/main.c b/init/main.c
> > > index 3b4ada1..6aba171 100644
> > > --- a/init/main.c
> > > +++ b/init/main.c
> > > @@ -92,6 +92,7 @@
> > > #include <linux rodata_test.h="">
> > > #include <linux jump_label.h="">
> > > #include <linux mem_encrypt.h="">
> > > +#include <linux audit.h="">
> > >
> > > #include <asm io.h="">
> > > #include <asm bugs.h="">
> > > @@ -721,6 +722,7 @@ asmlinkage __visible void __init
start_kernel(void)
> > > nsfs_init();
> > > cpuset_init();
> > > cgroup_init();
> > > + audit_task_init();
> > > taskstats_init_early();
> > > delayacct_init();
> >
> > It seems like we would need either init_struct_audit or
> > audit_task_init(), but not both, yes?
>
> One sets initial values of init task via an included struct,
other makes a call
> to create the kmem cache. Both seem appropriate to me unless we move the
> initialization from a struct to assignments in audit_task_init(),
but I'm not
> that comfortable separating the audit init values from the rest of the
> task_struct init task initializers (though there are other
subsystems that need
> to do so dynamically).
My original thinking was focused on the use of init_struct_audit as an
initializer when audit_task_init() was already creating a kmem_cache
pool and a zero'd/init'd audit_task_info could be obtained via the
usual kmem_cache functions. Alternatively, although I don't believe
it would be recommended for this case, would be to use
init_struct_audit as an init helper if we included the audit_task_info
struct directly in the task_struct, as opposed to a pointer. What I
missed was the simple fact that you're only using init_struct_audit
for the init_task, which pretty much makes my original question rather
silly :)
--
paul moore
www.paul-moore.com
- 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
--
paul moore
www.paul-moore.com
- 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,
On Tue, Jul 31, 2018 at 04:07:36PM -0400, Richard Guy Briggs wrote:
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API.
Collect the existing loginuid, sessionid and audit_context together in a
new struct audit_task_info called "audit" in struct task_struct.
Use kmem_cache to manage this pool of memory.
Un-inline audit_free() to be able to always recover that memory.
See: https://github.com/linux-audit/audit-kernel/issues/81
Signed-off-by: Richard Guy Briggs <redacted>
Overall I am not sure if keeping task_struct a bit smaller is worth
the added complexity, but I guess that is just me.
Anyway, couple of nitpicks. Please feel free to ignore, and my apologies
if some of all of the comments are duplicates.
Guenter
@@ -940,17 +949,28 @@ int audit_alloc(struct task_struct *tsk)structaudit_context*context;enumaudit_statestate;char*key=NULL;+structaudit_task_info*info;++info=kmem_cache_zalloc(audit_task_cache,GFP_KERNEL);+if(!info)+return-ENOMEM;+info->loginuid=audit_get_loginuid(current);+info->sessionid=audit_get_sessionid(current);+tsk->audit=info;if(likely(!audit_ever_enabled))return0;/* Return if not auditing. */state=audit_filter_task(tsk,&key);if(state==AUDIT_DISABLED){+audit_set_context(tsk,NULL);clear_tsk_thread_flag(tsk,TIF_SYSCALL_AUDIT);return0;}if(!(context=audit_alloc_context(state))){+tsk->audit=NULL;+kmem_cache_free(audit_task_cache,info);kfree(key);audit_log_lost("out of memory in audit_alloc");return-ENOMEM;
@@ -962,6 +982,12 @@ int audit_alloc(struct task_struct *tsk)return0;}+structaudit_task_infoinit_struct_audit={+.loginuid=INVALID_UID,+.sessionid=AUDIT_SID_UNSET,+.ctx=NULL,+};+staticinlinevoidaudit_free_context(structaudit_context*context){audit_free_names(context);
@@ -1469,26 +1495,33 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts}/**-*__audit_free-freeaper-taskauditcontext+*audit_free-freeaper-taskauditcontext*@tsk:taskwhoseauditcontextblocktofree**Calledfromcopy_processanddo_exit*/-void__audit_free(structtask_struct*tsk)+voidaudit_free(structtask_struct*tsk){structaudit_context*context;+structaudit_task_info*info;context=audit_take_context(tsk,0,0);-if(!context)-return;-/* Check for system calls that do not go through the exit*function(e.g.,exit_group),thenfreecontextblock.*WeuseGFP_ATOMICherebecausewemightbedoingthis*inthecontextoftheidlethread*//* that can happen only if we are called from do_exit() */-if(context->in_syscall&&context->current_state==AUDIT_RECORD_CONTEXT)+if(context&&context->in_syscall&&+context->current_state==AUDIT_RECORD_CONTEXT)audit_log_exit(context,tsk);+/* Freeing the audit_task_info struct must be performed after+*audit_log_exit()duetoneedforloginuidandsessionid.+*/+info=tsk->audit;+tsk->audit=NULL;+kmem_cache_free(audit_task_cache,info);+if(!context)+return;if(!list_empty(&context->killed_trees))audit_kill_trees(&context->killed_trees);
Looks kind of terrible with the repeated check if context is NULL.
Maybe reorder ?
context = audit_take_context(tsk, 0, 0);
if (context) {
/* do all the context work */
}
kmem_cache_free(audit_task_cache, tsk->audit);
tsk->audit = NULL; // is that even necessary ?
If "info" is really needed, ie if tsk (and tsk->audit) can be accessed
from another thread in parallel, I'd be a bit concerned about the lack
of sync() or similar after clearing tsk->audit.
Another option might have been to separate audit_free() into
audit_free_context() and audit_free_info().
From: Richard Guy Briggs <hidden> Date: 2019-01-04 14:57:35
On 2019-01-03 18:50, Guenter Roeck wrote:
Hi Richard,
On Tue, Jul 31, 2018 at 04:07:36PM -0400, Richard Guy Briggs wrote:
quoted
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API.
Collect the existing loginuid, sessionid and audit_context together in a
new struct audit_task_info called "audit" in struct task_struct.
Use kmem_cache to manage this pool of memory.
Un-inline audit_free() to be able to always recover that memory.
See: https://github.com/linux-audit/audit-kernel/issues/81
Signed-off-by: Richard Guy Briggs <redacted>
Overall I am not sure if keeping task_struct a bit smaller is worth
the added complexity, but I guess that is just me.
The motivation was to consolidate all the audit bits into one pointer,
isolating them from the rest of the kernel, restricting access only to
helper functions to prevent abuse by other subsystems and trying to
reduce kABI issues in the future. I agree it is a bit more complex. It
was provoked by the need to add contid which seemed to make the most
sense as a peer to loginuid and sessionid, and adding it to task_struct
would have made it a bit too generic and available.
This is addressed at some length by Paul Moore here in v2:
https://lkml.org/lkml/2018/4/18/759
Anyway, couple of nitpicks. Please feel free to ignore, and my apologies
if some of all of the comments are duplicates.
Noted. They all look like reasonable improvements, particulaly the
unnecessary else and default return. Thanks. The double context check
may go away anyways based on the removal of audit_take_context() in
Paul's 2a1fe215e730 ("audit: use current whenever possible") which has
yet to be incorporated.
@@ -940,17 +949,28 @@ int audit_alloc(struct task_struct *tsk)structaudit_context*context;enumaudit_statestate;char*key=NULL;+structaudit_task_info*info;++info=kmem_cache_zalloc(audit_task_cache,GFP_KERNEL);+if(!info)+return-ENOMEM;+info->loginuid=audit_get_loginuid(current);+info->sessionid=audit_get_sessionid(current);+tsk->audit=info;if(likely(!audit_ever_enabled))return0;/* Return if not auditing. */state=audit_filter_task(tsk,&key);if(state==AUDIT_DISABLED){+audit_set_context(tsk,NULL);clear_tsk_thread_flag(tsk,TIF_SYSCALL_AUDIT);return0;}if(!(context=audit_alloc_context(state))){+tsk->audit=NULL;+kmem_cache_free(audit_task_cache,info);kfree(key);audit_log_lost("out of memory in audit_alloc");return-ENOMEM;
@@ -962,6 +982,12 @@ int audit_alloc(struct task_struct *tsk)return0;}+structaudit_task_infoinit_struct_audit={+.loginuid=INVALID_UID,+.sessionid=AUDIT_SID_UNSET,+.ctx=NULL,+};+staticinlinevoidaudit_free_context(structaudit_context*context){audit_free_names(context);
@@ -1469,26 +1495,33 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts}/**-*__audit_free-freeaper-taskauditcontext+*audit_free-freeaper-taskauditcontext*@tsk:taskwhoseauditcontextblocktofree**Calledfromcopy_processanddo_exit*/-void__audit_free(structtask_struct*tsk)+voidaudit_free(structtask_struct*tsk){structaudit_context*context;+structaudit_task_info*info;context=audit_take_context(tsk,0,0);-if(!context)-return;-/* Check for system calls that do not go through the exit*function(e.g.,exit_group),thenfreecontextblock.*WeuseGFP_ATOMICherebecausewemightbedoingthis*inthecontextoftheidlethread*//* that can happen only if we are called from do_exit() */-if(context->in_syscall&&context->current_state==AUDIT_RECORD_CONTEXT)+if(context&&context->in_syscall&&+context->current_state==AUDIT_RECORD_CONTEXT)audit_log_exit(context,tsk);+/* Freeing the audit_task_info struct must be performed after+*audit_log_exit()duetoneedforloginuidandsessionid.+*/+info=tsk->audit;+tsk->audit=NULL;+kmem_cache_free(audit_task_cache,info);+if(!context)+return;if(!list_empty(&context->killed_trees))audit_kill_trees(&context->killed_trees);
Looks kind of terrible with the repeated check if context is NULL.
Maybe reorder ?
context = audit_take_context(tsk, 0, 0);
if (context) {
/* do all the context work */
}
kmem_cache_free(audit_task_cache, tsk->audit);
tsk->audit = NULL; // is that even necessary ?
If "info" is really needed, ie if tsk (and tsk->audit) can be accessed
from another thread in parallel, I'd be a bit concerned about the lack
of sync() or similar after clearing tsk->audit.
Another option might have been to separate audit_free() into
audit_free_context() and audit_free_info().
- 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 Fri, Jan 04, 2019 at 09:57:35AM -0500, Richard Guy Briggs wrote:
On 2019-01-03 18:50, Guenter Roeck wrote:
quoted
Hi Richard,
On Tue, Jul 31, 2018 at 04:07:36PM -0400, Richard Guy Briggs wrote:
quoted
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API.
Collect the existing loginuid, sessionid and audit_context together in a
new struct audit_task_info called "audit" in struct task_struct.
Use kmem_cache to manage this pool of memory.
Un-inline audit_free() to be able to always recover that memory.
See: https://github.com/linux-audit/audit-kernel/issues/81
Signed-off-by: Richard Guy Briggs <redacted>
Overall I am not sure if keeping task_struct a bit smaller is worth
the added complexity, but I guess that is just me.
The motivation was to consolidate all the audit bits into one pointer,
isolating them from the rest of the kernel, restricting access only to
helper functions to prevent abuse by other subsystems and trying to
reduce kABI issues in the future. I agree it is a bit more complex. It
was provoked by the need to add contid which seemed to make the most
sense as a peer to loginuid and sessionid, and adding it to task_struct
would have made it a bit too generic and available.
This is addressed at some length by Paul Moore here in v2:
https://lkml.org/lkml/2018/4/18/759
That makes sense. Thanks a lot for the clarification.
Guenter
From: Richard Guy Briggs <hidden> Date: 2019-01-24 20:36:56
On 2019-01-03 15:10, Paul Moore wrote:
On Thu, Nov 1, 2018 at 6:07 PM Richard Guy Briggs [off-list ref] wrote:
quoted
On 2018-10-19 19:15, Paul Moore wrote:
quoted
On Sun, Aug 5, 2018 at 4:32 AM Richard Guy Briggs [off-list ref] wrote:
quoted
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API.
Collect the existing loginuid, sessionid and audit_context together in a
new struct audit_task_info called "audit" in struct task_struct.
Use kmem_cache to manage this pool of memory.
Un-inline audit_free() to be able to always recover that memory.
See: https://github.com/linux-audit/audit-kernel/issues/81
Signed-off-by: Richard Guy Briggs <redacted>
---
include/linux/audit.h | 34 ++++++++++++++++++++++++----------
include/linux/sched.h | 5 +----
init/init_task.c | 3 +--
init/main.c | 2 ++
kernel/auditsc.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
kernel/fork.c | 4 +++-
6 files changed, 73 insertions(+), 26 deletions(-)
Prior to this patch audit_context was available regardless of
CONFIG_AUDITSYSCALL, after this patch the corresponding audit_context
is only available when CONFIG_AUDITSYSCALL is defined.
This was intentional since audit_context is not used when AUDITSYSCALL is
disabled. audit_alloc() was stubbed in that case to return 0. audit_context()
returned NULL.
The fact that audit_context was still present in struct task_struct was an
oversight in the two patches already accepted:
("audit: use inline function to get audit context")
("audit: use inline function to get audit context")
that failed to hide or remove it from struct task_struct when it was no longer
relevant.
Okay, in that case let's pull this out and fix this separately from
the audit container ID patchset.
Ok, that should be addressed by ghak104.
quoted
On further digging, loginuid and sessionid (and audit_log_session_info) should
be part of CONFIG_AUDIT scope and not CONFIG_AUDITSYSCALL since it is used in
CONFIG_CHANGE, ANOM_LINK, FEATURE_CHANGE(, INTEGRITY_RULE), none of which are
otherwise dependent on AUDITSYSCALL.
This looks like something else we should fix independently from this patchset.
Ok, this should be addressed by ghak105.
quoted
Looking ahead, contid should be treated like loginuid and sessionid, which are
currently only available when syscall auditting is.
That seems reasonable. Eventually it would be great if we got rid of
CONFIG_AUDITSYSCALL, but that is a separate issue, and something that
is going to require work from the different arch/ABI folks to ensure
everything is working properly.
So I'll plan to rebase on ghak104 and ghak105 once they are upstreamed.
I'll address the locking issues in the netns list and audit_sig_cid...
quoted
Converting records from standalone to syscall and checking audit_dummy_context
changes the nature of CONFIG_AUDIT/!CONFIG_AUDITSYSCALL separation.
eg: ANOM_LINK accompanied by PATH record (which needed CWD addition to be
complete anyways)
This has been addressed in ghak105, moving ANOM_LINK to auditsc.
paul moore
- 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