[PATCH ghau40 v2 4/5] add ausearch containerid support

2018-03-16 Thread Richard Guy Briggs
Add support to ausearch for searching on the containerid field in
records.

Signed-off-by: Richard Guy Briggs 
---
 src/aureport-options.c |   1 +
 src/ausearch-llist.c   |   2 +
 src/ausearch-llist.h   |   1 +
 src/ausearch-match.c   |   3 +
 src/ausearch-options.c |  46 -
 src/ausearch-options.h |   1 +
 src/ausearch-parse.c   | 171 +
 7 files changed, 224 insertions(+), 1 deletion(-)

diff --git a/src/aureport-options.c b/src/aureport-options.c
index 9b914ed..436 100644
--- a/src/aureport-options.c
+++ b/src/aureport-options.c
@@ -62,6 +62,7 @@ const char *event_vmname = NULL;
 long long event_exit = 0;
 int event_exit_is_set = 0;
 int event_ppid = -1, event_session_id = -2;
+unsigned long long int event_container_id = -2;
 int event_debug = 0, event_machine = -1;
 
 /* These are used by aureport */
diff --git a/src/ausearch-llist.c b/src/ausearch-llist.c
index ef5503c..c910724 100644
--- a/src/ausearch-llist.c
+++ b/src/ausearch-llist.c
@@ -60,6 +60,7 @@ void list_create(llist *l)
l->s.arch = 0;
l->s.syscall = 0;
l->s.session_id = -2;
+   l->s.container_id = -2;
l->s.uuid = NULL;
l->s.vmname = NULL;
l->s.tuid = NULL;
@@ -211,6 +212,7 @@ void list_clear(llist* l)
l->s.arch = 0;
l->s.syscall = 0;
l->s.session_id = -2;
+   l->s.container_id = -2;
free(l->s.uuid);
l->s.uuid = NULL;
free(l->s.vmname);
diff --git a/src/ausearch-llist.h b/src/ausearch-llist.h
index 64e4ee1..1c651c5 100644
--- a/src/ausearch-llist.h
+++ b/src/ausearch-llist.h
@@ -56,6 +56,7 @@ typedef struct
   int arch; // arch
   int syscall;  // syscall
   uint32_t session_id;  // Login session id
+  __u64 container_id;// Container id
   long long exit;   // Syscall exit code
   int exit_is_set;  // Syscall exit code is valid
   char *hostname;   // remote hostname
diff --git a/src/ausearch-match.c b/src/ausearch-match.c
index 61a11d3..51dccb0 100644
--- a/src/ausearch-match.c
+++ b/src/ausearch-match.c
@@ -113,6 +113,9 @@ int match(llist *l)
if ((event_session_id != -2) &&
(event_session_id != l->s.session_id))
return 0;
+   if ((event_container_id != -2) &&
+   (event_container_id != 
l->s.container_id))
+   return 0;
if (event_exit_is_set) {
if (l->s.exit_is_set == 0)
return 0;
diff --git a/src/ausearch-options.c b/src/ausearch-options.c
index a3f08e7..1d095a7 100644
--- a/src/ausearch-options.c
+++ b/src/ausearch-options.c
@@ -60,6 +60,7 @@ int event_syscall = -1, event_machine = -1;
 int event_ua = 0, event_ga = 0, event_se = 0;
 int just_one = 0;
 uint32_t event_session_id = -2;
+unsigned long long int event_container_id = -2;
 long long event_exit = 0;
 int event_exit_is_set = 0;
 int line_buffered = 0;
@@ -88,7 +89,7 @@ struct nv_pair {
 
 enum { S_EVENT, S_COMM, S_FILENAME, S_ALL_GID, S_EFF_GID, S_GID, S_HELP,
 S_HOSTNAME, S_INTERP, S_INFILE, S_MESSAGE_TYPE, S_PID, S_SYSCALL, S_OSUCCESS,
-S_TIME_END, S_TIME_START, S_TERMINAL, S_ALL_UID, S_EFF_UID, S_UID, S_LOGINID,
+S_TIME_END, S_TIME_START, S_TERMINAL, S_ALL_UID, S_EFF_UID, S_UID, S_LOGINID, 
S_CONTAINERID,
 S_VERSION, S_EXACT_MATCH, S_EXECUTABLE, S_CONTEXT, S_SUBJECT, S_OBJECT,
 S_PPID, S_KEY, S_RAW, S_NODE, S_IN_LOGS, S_JUST_ONE, S_SESSION, S_EXIT,
 S_LINEBUFFERED, S_UUID, S_VMNAME, S_DEBUG, S_CHECKPOINT, S_ARCH, S_FORMAT,
@@ -169,6 +170,7 @@ static struct nv_pair optiontab[] = {
{ S_UUID, "--uuid" },
{ S_LOGINID, "-ul" },
{ S_LOGINID, "--loginuid" },
+   { S_CONTAINERID, "--containerid" },
{ S_VERSION, "-v" },
{ S_VERSION, "--version" },
{ S_VMNAME, "-vm" },
@@ -1182,6 +1184,48 @@ int check_params(int count, char *vars[])
}
c++;
break;
+   case S_CONTAINERID:
+   if (!optarg) {
+   if ((c+1 < count) && vars[c+1])
+   optarg = vars[c+1];
+   else {
+   fprintf(stderr,
+   "Argument is required for %s\n",
+   vars[c]);
+   retval = -1;
+   break;
+   }
+   }
+   {
+   size_t len = strlen(optarg);
+   if (isdigit(optarg[0])) {
+   errno = 0;
+   

[PATCH ghau40 v2 3/5] auditctl: add support for containerid filter

2018-03-16 Thread Richard Guy Briggs
A u64 container identifier has been added to the kernel view of tasks.
This allows container orchestrators to label tasks with a unique
tamperproof identifier that gets inherited by its children to be able to
track the provenance of actions by a container.

Add support to libaudit and auditctl for the containerid field to filter
based on container identifier.  Since it is a u64 and larger than any
other numeric field, send it as a string but do the appropriate
conversions on each end in each direction.

See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-kernel/issues/32
See: https://github.com/linux-audit/audit-testsuite/issues/64
Signed-off-by: Richard Guy Briggs 
---
 docs/auditctl.8|  3 +++
 lib/fieldtab.h |  1 +
 lib/libaudit.c | 36 
 lib/libaudit.h |  7 +++
 src/auditctl-listing.c | 21 +
 5 files changed, 68 insertions(+)

diff --git a/docs/auditctl.8 b/docs/auditctl.8
index 88466de..8bda43d 100644
--- a/docs/auditctl.8
+++ b/docs/auditctl.8
@@ -210,6 +210,9 @@ Parent's Process ID
 .B sessionid
 User's login session ID
 .TP
+.B containerid
+Process' container ID
+.TP
 .B subj_user
 Program's SE Linux User
 .TP
diff --git a/lib/fieldtab.h b/lib/fieldtab.h
index c425d5b..755800a 100644
--- a/lib/fieldtab.h
+++ b/lib/fieldtab.h
@@ -47,6 +47,7 @@ _S(AUDIT_OBJ_TYPE, "obj_type" )
 _S(AUDIT_OBJ_LEV_LOW,  "obj_lev_low"  )
 _S(AUDIT_OBJ_LEV_HIGH, "obj_lev_high" )
 _S(AUDIT_SESSIONID,"sessionid")
+_S(AUDIT_CONTAINERID,  "containerid"  )
 
 _S(AUDIT_DEVMAJOR, "devmajor" )
 _S(AUDIT_DEVMINOR, "devminor" )
diff --git a/lib/libaudit.c b/lib/libaudit.c
index 331cdde..c45f366 100644
--- a/lib/libaudit.c
+++ b/lib/libaudit.c
@@ -1737,6 +1737,42 @@ int audit_rule_fieldpair_data(struct audit_rule_data 
**rulep, const char *pair,
else if (strcmp(v, "unset") == 0)
rule->values[rule->field_count] = UINT_MAX;
break;
+   case AUDIT_CONTAINERID: {
+   unsigned long long val;
+
+   if ((audit_get_features() &
+   AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER) == 0)
+   return -EAU_FIELDNOSUPPORT;
+   if (flags != AUDIT_FILTER_EXCLUDE &&
+   flags != AUDIT_FILTER_USER &&
+   flags != AUDIT_FILTER_EXIT)
+   return -EAU_FIELDNOFILTER;
+   if (isdigit((char)*(v))) 
+   val = strtoull(v, NULL, 0);
+   else if (strlen(v) >= 2 && *(v)=='-' && 
+   (isdigit((char)*(v+1 
+   val = strtoll(v, NULL, 0);
+   else if (strcmp(v, "unset") == 0)
+   val = ULLONG_MAX;
+   else
+   return -EAU_FIELDVALNUM;
+   if (errno)
+   return -EAU_FIELDVALNUM;
+   vlen = sizeof(unsigned long long);
+   rule->values[rule->field_count] = vlen;
+   offset = rule->buflen;
+   rule->buflen += vlen;
+   *rulep = realloc(rule, sizeof(*rule) + rule->buflen);
+   if (*rulep == NULL) {
+   free(rule);
+   audit_msg(LOG_ERR, "Cannot realloc memory!\n");
+   return -3;
+   } else {
+   rule = *rulep;
+   }
+   *(unsigned long long*)(>buf[offset]) = val;
+   break;
+   }
case AUDIT_DEVMAJOR...AUDIT_INODE:
case AUDIT_SUCCESS:
if (flags != AUDIT_FILTER_EXIT)
diff --git a/lib/libaudit.h b/lib/libaudit.h
index 756a3b8..cefe71d 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -328,6 +328,9 @@ extern "C" {
 #ifndef AUDIT_FEATURE_BITMAP_FILTER_FS
 #define AUDIT_FEATURE_BITMAP_FILTER_FS 0x0040
 #endif
+#ifndef AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER
+#define AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER 0x0080
+#endif
 
 /* Defines for interfield comparison update */
 #ifndef AUDIT_OBJ_UID
@@ -351,6 +354,10 @@ extern "C" {
 #define AUDIT_FSTYPE 26
 #endif
 
+#ifndef AUDIT_CONTAINERID
+#define AUDIT_CONTAINERID 27
+#endif
+
 #ifndef AUDIT_COMPARE_UID_TO_OBJ_UID
 #define AUDIT_COMPARE_UID_TO_OBJ_UID   1
 #endif
diff --git a/src/auditctl-listing.c b/src/auditctl-listing.c
index f670ff9..974dcb4 100644
--- a/src/auditctl-listing.c
+++ b/src/auditctl-listing.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 

[PATCH ghau40 v2 5/5] start normalization containerid support

2018-03-16 Thread Richard Guy Briggs
Signed-off-by: Richard Guy Briggs 
---
 auparse/normalize_record_map.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/auparse/normalize_record_map.h b/auparse/normalize_record_map.h
index 1507bb5..c529e2e 100644
--- a/auparse/normalize_record_map.h
+++ b/auparse/normalize_record_map.h
@@ -25,6 +25,7 @@
 
 _S(AUDIT_USER, "sent-message")
 _S(AUDIT_LOGIN, "changed-login-id-to")
+_S(AUDIT_CONTAINER, "changed-container-id-to")
 _S(AUDIT_USER_AUTH, "authenticated")
 _S(AUDIT_USER_ACCT, "was-authorized")
 _S(AUDIT_USER_MGMT, "modified-user-account")
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[PATCH ghau40 v2 2/5] AUDIT_CONTAINER_INFO message type basic support

2018-03-16 Thread Richard Guy Briggs
This defines the message number for the container ID info record should
the kernel headers not be up to date and gives the record number a name for
printing.

Signed-off-by: Richard Guy Briggs 
---
 lib/libaudit.h| 4 
 lib/msg_typetab.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/lib/libaudit.h b/lib/libaudit.h
index 6d431b9..756a3b8 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -282,6 +282,10 @@ extern "C" {
 #define AUDIT_FANOTIFY 1331 /* Fanotify access decision */
 #endif
 
+#ifndef AUDIT_CONTAINER_INFO
+#define AUDIT_CONTAINER_INFO1332 /* Container ID details */
+#endif
+
 #ifndef AUDIT_ANOM_LINK
 #define AUDIT_ANOM_LINK1702 /* Suspicious use of file links */
 #endif
diff --git a/lib/msg_typetab.h b/lib/msg_typetab.h
index e2fd536..5c4892a 100644
--- a/lib/msg_typetab.h
+++ b/lib/msg_typetab.h
@@ -124,6 +124,7 @@ _S(AUDIT_PROCTITLE,  "PROCTITLE"
 )
 _S(AUDIT_FEATURE_CHANGE, "FEATURE_CHANGE")
 _S(AUDIT_KERN_MODULE,"KERN_MODULE"   )
 _S(AUDIT_FANOTIFY,   "FANOTIFY"  )
+_S(AUDIT_CONTAINER_INFO, "CONTAINER_INFO")
 _S(AUDIT_AVC,"AVC"   )
 _S(AUDIT_SELINUX_ERR,"SELINUX_ERR"   )
 _S(AUDIT_AVC_PATH,   "AVC_PATH"  )
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[PATCH ghau40 v2 1/5] AUDIT_CONTAINER message type basic support

2018-03-16 Thread Richard Guy Briggs
This defines the message number for the container ID registration record
should the kernel headers not be up to date, gives the record number a
name for printing and allows the record to be interpreted since it is in
the 1000 range like AUDIT_LOGIN.

Signed-off-by: Richard Guy Briggs 
---
 lib/libaudit.h| 4 
 lib/msg_typetab.h | 1 +
 lib/netlink.c | 1 +
 3 files changed, 6 insertions(+)

diff --git a/lib/libaudit.h b/lib/libaudit.h
index b681e8d..6d431b9 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -242,6 +242,10 @@ extern "C" {
 #define AUDIT_GET_FEATURE   1019/* Get which features are enabled */
 #endif
 
+#ifndef AUDIT_CONTAINER
+#define AUDIT_CONTAINER 1020/* Container creation notice */
+#endif
+
 #ifndef AUDIT_MMAP
 #define AUDIT_MMAP 1323 /* Descriptor and flags in mmap */
 #endif
diff --git a/lib/msg_typetab.h b/lib/msg_typetab.h
index 966865f..e2fd536 100644
--- a/lib/msg_typetab.h
+++ b/lib/msg_typetab.h
@@ -44,6 +44,7 @@ _S(AUDIT_LOGIN,  "LOGIN"  
   )
 //_S(AUDIT_TTY_SET,"TTY_SET"   )
 //_S(AUDIT_SET_FEATURE,"SET_FEATURE"   )
 //_S(AUDIT_GET_FEATURE,"GET_FEATURE"   )
+_S(AUDIT_CONTAINER,  "CONTAINER" )
 _S(AUDIT_USER_AUTH,  "USER_AUTH" )
 _S(AUDIT_USER_ACCT,  "USER_ACCT" )
 _S(AUDIT_USER_MGMT,  "USER_MGMT" )
diff --git a/lib/netlink.c b/lib/netlink.c
index 5b2028f..8847875 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -184,6 +184,7 @@ static int adjust_reply(struct audit_reply *rep, int len)
break;
case AUDIT_USER:
case AUDIT_LOGIN:
+   case AUDIT_CONTAINER:
case AUDIT_KERNEL:
case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[PATCH ghau40 v2 0/5] add support for audit container ID

2018-03-16 Thread Richard Guy Briggs
Add support for audit kernel container IDs to userspace tools.

See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-kernel/issues/32
See: https://github.com/linux-audit/audit-testsuite/issues/64

Richard Guy Briggs (5):
  AUDIT_CONTAINER message type basic support
  AUDIT_CONTAINER_INFO message type basic support
  auditctl: add support for containerid filter
  add ausearch containerid support
  start normalization containerid support

 auparse/normalize_record_map.h |   1 +
 docs/auditctl.8|   3 +
 lib/fieldtab.h |   1 +
 lib/libaudit.c |  36 +
 lib/libaudit.h |  15 
 lib/msg_typetab.h  |   2 +
 lib/netlink.c  |   1 +
 src/auditctl-listing.c |  21 +
 src/aureport-options.c |   1 +
 src/ausearch-llist.c   |   2 +
 src/ausearch-llist.h   |   1 +
 src/ausearch-match.c   |   3 +
 src/ausearch-options.c |  46 ++-
 src/ausearch-options.h |   1 +
 src/ausearch-parse.c   | 171 +
 15 files changed, 304 insertions(+), 1 deletion(-)

-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[RFC PATCH ghak32 V2 11/13] audit: add support for containerid to network namespaces

2018-03-16 Thread Richard Guy Briggs
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 container identifiiers.

Add/increment the container identifier on:
- initial setting of the container id via /proc
- clone/fork call that inherits a container identifier
- unshare call that inherits a container identifier
- setns call that inherits a container identifier
Delete/decrement the container identifier on:
- an inherited container id 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/32
See: https://github.com/linux-audit/audit-testsuite/issues/64
Signed-off-by: Richard Guy Briggs 
---
 include/linux/audit.h   |  7 +++
 include/net/net_namespace.h | 12 
 kernel/auditsc.c|  9 ++---
 kernel/nsproxy.c|  6 ++
 net/core/net_namespace.c| 45 +
 5 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index c0b83cb..d9afb7d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define AUDIT_INO_UNSET ((unsigned long)-1)
 #define AUDIT_DEV_UNSET ((dev_t)-1)
@@ -88,6 +89,12 @@ struct audit_field {
u32 op;
 };
 
+struct audit_containerid {
+   struct list_headlist;
+   u64 id;
+   refcount_t  refcount;
+};
+
 extern int is_audit_feature_set(int which);
 
 extern int __init audit_register_class(int class, unsigned *list);
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 0490084..343a428 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct user_namespace;
 struct proc_dir_entry;
@@ -150,6 +151,7 @@ struct net {
 #endif
struct sock *diag_nlsk;
atomic_tfnhe_genid;
+   struct list_headaudit_containerid;
 } __randomize_layout;
 
 #include 
@@ -301,6 +303,16 @@ static inline struct net *read_pnet(const possible_net_t 
*pnet)
 #define __net_initconst__initconst
 #endif
 
+#ifdef CONFIG_NET_NS
+void net_add_audit_containerid(struct net *net, u64 containerid);
+void net_del_audit_containerid(struct net *net, u64 containerid);
+#else
+static inline void net_add_audit_containerid(struct net *, u64)
+{ }
+static inline void net_del_audit_containerid(struct net *, u64)
+{ }
+#endif
+
 int peernet2id_alloc(struct net *net, struct net *peer);
 int peernet2id(struct net *net, struct net *peer);
 bool peernet_has_id(struct net *net, struct net *peer);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2f02ed9..208da962 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -75,6 +75,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "audit.h"
 
@@ -2175,16 +2176,18 @@ static void audit_log_set_containerid(struct 
task_struct *task, u64 oldcontainer
  */
 int audit_set_containerid(struct task_struct *task, u64 containerid)
 {
-   u64 oldcontainerid;
+   u64 oldcontainerid = audit_get_containerid(task);
int rc;
-
-   oldcontainerid = audit_get_containerid(task);
+   struct net *net = task->nsproxy->net_ns;
 
rc = audit_set_containerid_perm(task, containerid);
if (!rc) {
+   if (cid_valid(oldcontainerid))
+   net_del_audit_containerid(net, oldcontainerid);
task_lock(task);
task->containerid = containerid;
task_unlock(task);
+   net_add_audit_containerid(net, containerid);
}
 
audit_log_set_containerid(task, oldcontainerid, containerid, rc);
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index f6c5d33..d9f1090 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -140,6 +140,7 @@ int copy_namespaces(unsigned long flags, struct task_struct 
*tsk)
struct nsproxy *old_ns = tsk->nsproxy;
struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
struct nsproxy *new_ns;
+   u64 containerid = audit_get_containerid(tsk);
 
if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
  CLONE_NEWPID | CLONE_NEWNET |
@@ -167,6 +168,7 @@ int copy_namespaces(unsigned long flags, struct task_struct 
*tsk)
return  PTR_ERR(new_ns);
 
tsk->nsproxy = new_ns;
+   net_add_audit_containerid(new_ns->net_ns, containerid);

[RFC PATCH ghak32 V2 12/13] audit: NETFILTER_PKT: record each container ID associated with a netNS

2018-03-16 Thread Richard Guy Briggs
Add container ID auxiliary record(s) to NETFILTER_PKT event standalone
records.  Iterate through all potential container IDs associated with a
network namespace.

Signed-off-by: Richard Guy Briggs 
---
 kernel/audit.c   |  1 +
 kernel/auditsc.c |  2 ++
 net/netfilter/xt_AUDIT.c | 15 ++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 08662b4..3c77e47 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2102,6 +2102,7 @@ int audit_log_container_info(struct audit_context 
*context,
audit_log_end(ab);
return 0;
 }
+EXPORT_SYMBOL(audit_log_container_info);
 
 void audit_log_key(struct audit_buffer *ab, char *key)
 {
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 208da962..af68d01 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -975,6 +975,7 @@ struct audit_context *audit_alloc_local(void)
context->in_syscall = 1;
return context;
 }
+EXPORT_SYMBOL(audit_alloc_local);
 
 inline void audit_free_context(struct audit_context *context)
 {
@@ -989,6 +990,7 @@ inline void audit_free_context(struct audit_context 
*context)
audit_proctitle_free(context);
kfree(context);
 }
+EXPORT_SYMBOL(audit_free_context);
 
 static int audit_log_pid_context(struct audit_context *context, pid_t pid,
 kuid_t auid, kuid_t uid, unsigned int 
sessionid,
diff --git a/net/netfilter/xt_AUDIT.c b/net/netfilter/xt_AUDIT.c
index c502419..edaa456 100644
--- a/net/netfilter/xt_AUDIT.c
+++ b/net/netfilter/xt_AUDIT.c
@@ -71,10 +71,14 @@ static bool audit_ip6(struct audit_buffer *ab, struct 
sk_buff *skb)
 {
struct audit_buffer *ab;
int fam = -1;
+   struct audit_context *context = audit_alloc_local();
+   struct audit_containerid *cont;
+   int i = 0;
+   struct net *net;
 
if (audit_enabled == 0)
goto errout;
-   ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
+   ab = audit_log_start(context, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
if (ab == NULL)
goto errout;
 
@@ -104,7 +108,16 @@ static bool audit_ip6(struct audit_buffer *ab, struct 
sk_buff *skb)
 
audit_log_end(ab);
 
+   net = sock_net(NETLINK_CB(skb).sk);
+   list_for_each_entry(cont, >audit_containerid, list) {
+   char buf[14];
+
+   sprintf(buf, "net%u", i++);
+   audit_log_container_info(context, buf, cont->id);
+   }
+
 errout:
+   audit_free_context(context);
return XT_CONTINUE;
 }
 
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[RFC PATCH ghak32 V2 06/13] audit: add support for non-syscall auxiliary records

2018-03-16 Thread Richard Guy Briggs
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 
---
 include/linux/audit.h |  8 
 kernel/auditsc.c  | 20 +++-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index ed16bb6..c0b83cb 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -227,7 +227,9 @@ static inline int audit_log_container_info(struct 
audit_context *context,
 /* These are defined in auditsc.c */
/* Public API */
 extern int  audit_alloc(struct task_struct *task);
+extern struct audit_context *audit_alloc_local(void);
 extern void __audit_free(struct task_struct *task);
+extern void audit_free_context(struct audit_context *context);
 extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long 
a1,
  unsigned long a2, unsigned long a3);
 extern void __audit_syscall_exit(int ret_success, long ret_value);
@@ -472,6 +474,12 @@ static inline int audit_alloc(struct task_struct *task)
 {
return 0;
 }
+static inline struct audit_context *audit_alloc_local(void)
+{
+   return NULL;
+}
+static inline void audit_free_context(struct audit_context *context)
+{ }
 static inline void audit_free(struct task_struct *task)
 { }
 static inline void audit_syscall_entry(int major, unsigned long a0,
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2932ef1..7103d23 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -959,8 +959,26 @@ int audit_alloc(struct task_struct *tsk)
return 0;
 }
 
-static inline void audit_free_context(struct audit_context *context)
+struct audit_context *audit_alloc_local(void)
 {
+   struct audit_context *context;
+
+   if (!audit_ever_enabled)
+   return NULL; /* Return if not auditing. */
+
+   context = audit_alloc_context(AUDIT_RECORD_CONTEXT);
+   if (!context)
+   return NULL;
+   context->serial = audit_serial();
+   context->ctime = current_kernel_time64();
+   context->in_syscall = 1;
+   return context;
+}
+
+inline void audit_free_context(struct audit_context *context)
+{
+   if (!context)
+   return;
audit_free_names(context);
unroll_tree_refs(context, NULL, 0);
free_tree_refs(context);
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[RFC PATCH ghak32 V2 07/13] audit: add container aux record to watch/tree/mark

2018-03-16 Thread Richard Guy Briggs
Add container ID auxiliary record to mark, watch and tree rule
configuration standalone records.

Signed-off-by: Richard Guy Briggs 
---
 kernel/audit_fsnotify.c |  5 -
 kernel/audit_tree.c |  5 -
 kernel/audit_watch.c| 33 +++--
 3 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
index 52f368b..18c110d 100644
--- a/kernel/audit_fsnotify.c
+++ b/kernel/audit_fsnotify.c
@@ -124,10 +124,11 @@ static void audit_mark_log_rule_change(struct 
audit_fsnotify_mark *audit_mark, c
 {
struct audit_buffer *ab;
struct audit_krule *rule = audit_mark->rule;
+   struct audit_context *context = audit_alloc_local();
 
if (!audit_enabled)
return;
-   ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
+   ab = audit_log_start(context, GFP_NOFS, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return;
audit_log_format(ab, "auid=%u ses=%u op=%s",
@@ -138,6 +139,8 @@ static void audit_mark_log_rule_change(struct 
audit_fsnotify_mark *audit_mark, c
audit_log_key(ab, rule->filterkey);
audit_log_format(ab, " list=%d res=1", rule->listnr);
audit_log_end(ab);
+   audit_log_container_info(context, "config", 
audit_get_containerid(current));
+   audit_free_context(context);
 }
 
 void audit_remove_mark(struct audit_fsnotify_mark *audit_mark)
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 67e6956..7c085be 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -496,8 +496,9 @@ static int tag_chunk(struct inode *inode, struct audit_tree 
*tree)
 static void audit_tree_log_remove_rule(struct audit_krule *rule)
 {
struct audit_buffer *ab;
+   struct audit_context *context = audit_alloc_local();
 
-   ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+   ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return;
audit_log_format(ab, "op=remove_rule");
@@ -506,6 +507,8 @@ static void audit_tree_log_remove_rule(struct audit_krule 
*rule)
audit_log_key(ab, rule->filterkey);
audit_log_format(ab, " list=%d res=1", rule->listnr);
audit_log_end(ab);
+   audit_log_container_info(context, "config", 
audit_get_containerid(current));
+   audit_free_context(context);
 }
 
 static void kill_rules(struct audit_tree *tree)
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 9eb8b35..60d75a2 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -238,20 +238,25 @@ static struct audit_watch *audit_dupe_watch(struct 
audit_watch *old)
 
 static void audit_watch_log_rule_change(struct audit_krule *r, struct 
audit_watch *w, char *op)
 {
-   if (audit_enabled) {
-   struct audit_buffer *ab;
-   ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
-   if (unlikely(!ab))
-   return;
-   audit_log_format(ab, "auid=%u ses=%u op=%s",
-from_kuid(_user_ns, 
audit_get_loginuid(current)),
-audit_get_sessionid(current), op);
-   audit_log_format(ab, " path=");
-   audit_log_untrustedstring(ab, w->path);
-   audit_log_key(ab, r->filterkey);
-   audit_log_format(ab, " list=%d res=1", r->listnr);
-   audit_log_end(ab);
-   }
+   struct audit_buffer *ab;
+   struct audit_context *context = audit_alloc_local();
+
+   if (!audit_enabled)
+   return;
+
+   ab = audit_log_start(context, GFP_NOFS, AUDIT_CONFIG_CHANGE);
+   if (unlikely(!ab))
+   return;
+   audit_log_format(ab, "auid=%u ses=%u op=%s",
+from_kuid(_user_ns, audit_get_loginuid(current)),
+audit_get_sessionid(current), op);
+   audit_log_format(ab, " path=");
+   audit_log_untrustedstring(ab, w->path);
+   audit_log_key(ab, r->filterkey);
+   audit_log_format(ab, " list=%d res=1", r->listnr);
+   audit_log_end(ab);
+   audit_log_container_info(context, "config", 
audit_get_containerid(current));
+   audit_free_context(context);
 }
 
 /* Update inode info in audit rules based on filesystem event. */
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[RFC PATCH ghak32 V2 00/13] audit: implement container id

2018-03-16 Thread Richard Guy Briggs
Implement audit kernel container ID.

This patchset is a second RFC based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html

The first patch implements the proc fs write to set the audit container
ID of a process, emitting an AUDIT_CONTAINER record to announce the
registration of that container ID on that process.  This patch requires
userspace support for record acceptance and proper type display.

The second checks for children or co-threads and refuses to set the
container ID if either are present.  (This policy could be changed to
set both with the same container ID provided they meet the rest of the
requirements.)

The third implements the auxiliary record AUDIT_CONTAINER_INFO if a
container ID is identifiable with an event.  This patch requires
userspace support for proper type display.

The fourth adds container ID filtering to the exit, exclude and user
lists.  This patch requires auditctil userspace support for the
--containerid option.

The 5th adds signal and ptrace support.

The 6th creates a local audit context to be able to bind a standalone
record with a locally created auxiliary record.

The 7th, 8th, 9th, 10th patches add container ID records to standalone
records.  Some of these may end up being syscall auxiliary records and
won't need this specific support since they'll be supported via
syscalls.

The 11th adds network namespace container ID labelling based on member
tasks' container ID labels.

The 12th adds container ID support to standalone netfilter records that
don't have a task context and lists each container to which that net
namespace belongs.

The 13th implements reading the container ID from the proc filesystem
for debugging.  This patch isn't planned for upstream inclusion.

Feedback please!

Example: Set a container ID of 123456 to the "sleep" task:
sleep 2&  
child=$!
echo 123456 > /proc/$child/containerid; echo $?
ausearch -ts recent -m container
echo child:$child contid:$( cat /proc/$child/containerid)
This should produce a record such as:
type=CONTAINER msg=audit(1521122590.315:222): op=set pid=689 uid=0 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 
ses=3 opid=707 old-contid=18446744073709551615 contid=123456 res=1

Example: Set a filter on a container ID 123459 on /tmp/tmpcontainerid:
containerid=123459
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F 
containerid=$containerid -F key=$key
perl -e "sleep 1; open(my \$tmpfile, '>', \"/tmp/$key\"); 
close(\$tmpfile);" &
child=$!
echo $containerid > /proc/$child/containerid
sleep 2
ausearch -i -ts recent -k $key
auditctl -d exit,always -F dir=/tmp -F perm=wa -F 
containerid=$containerid -F key=$key
rm -f /tmp/$key
This should produce an event such as:
type=CONTAINER_INFO msg=audit(1521122591.614:227): op=task contid=123459
type=PROCTITLE msg=audit(1521122591.614:227): 
proctitle=7065726C002D6500736C65657020313B206F70656E286D792024746D7066696C652C20273E272C20222F746D702F746D70636F6E7461696E6572696422293B20636C6F73652824746D7066696C65293B
type=PATH msg=audit(1521122591.614:227): item=1 
name="/tmp/tmpcontainerid" inode=18427 dev=00:26 mode=0100644 ouid=0 ogid=0 
rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE 
cap_fp= cap_fi= cap_fe=0 cap_fver=0
type=PATH msg=audit(1521122591.614:227): item=0 name="/tmp/" 
inode=13513 dev=00:26 mode=041777 ouid=0 ogid=0 rdev=00:00 
obj=system_u:object_r:tmp_t:s0 nametype=PARENT cap_fp= 
cap_fi= cap_fe=0 cap_fver=0
type=CWD msg=audit(1521122591.614:227): cwd="/root"
type=SYSCALL msg=audit(1521122591.614:227): arch=c03e syscall=257 
success=yes exit=3 a0=ff9c a1=55db90a28900 a2=241 a3=1b6 items=2 
ppid=689 pid=724 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 
tty=pts0 ses=3 comm="perl" exe="/usr/bin/perl" 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="tmpcontainerid"

See:
https://github.com/linux-audit/audit-kernel/issues/32
https://github.com/linux-audit/audit-userspace/issues/40
https://github.com/linux-audit/audit-testsuite/issues/64

Richard Guy Briggs (13):
  audit: add container id
  audit: check children and threading before allowing containerid
  audit: log container info of syscalls
  audit: add containerid filtering
  audit: add containerid support for ptrace and signals
  audit: add support for non-syscall auxiliary records
  audit: add container aux record to watch/tree/mark
  audit: add containerid support for tty_audit
  audit: add containerid support for config/feature/user records
  audit: add containerid support for seccomp and anom_abend records
  audit: add support for containerid to network namespaces
  audit: NETFILTER_PKT: 

[RFC PATCH ghak32 V2 05/13] audit: add containerid support for ptrace and signals

2018-03-16 Thread Richard Guy Briggs
Add container ID support to ptrace and signals.  In particular, the "op"
field provides a way to label the auxiliary record to which it is
associated.

Signed-off-by: Richard Guy Briggs 
---
 include/linux/audit.h | 16 +++-
 kernel/audit.c| 12 
 kernel/audit.h|  2 ++
 kernel/auditsc.c  | 19 +++
 4 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index f10ca1b..ed16bb6 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -35,6 +35,7 @@ struct audit_sig_info {
uid_t   uid;
pid_t   pid;
charctx[0];
+   u64 cid;
 };
 
 struct audit_buffer;
@@ -155,8 +156,8 @@ extern void audit_log_link_denied(const char 
*operation,
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk);
-extern int audit_log_container_info(struct task_struct *tsk,
-struct audit_context *context);
+extern int audit_log_container_info(struct audit_context *context,
+char *op, u64 containerid);
 
 extern int audit_update_lsm_rules(void);
 
@@ -208,8 +209,8 @@ static inline int audit_log_task_context(struct 
audit_buffer *ab)
 static inline void audit_log_task_info(struct audit_buffer *ab,
   struct task_struct *tsk)
 { }
-static inline int audit_log_container_info(struct task_struct *tsk,
-   struct audit_context *context);
+static inline int audit_log_container_info(struct audit_context *context,
+   char *op, u64 containerid);
 { }
 #define audit_enabled 0
 #endif /* CONFIG_AUDIT */
@@ -598,9 +599,14 @@ static inline bool audit_loginuid_set(struct task_struct 
*tsk)
return uid_valid(audit_get_loginuid(tsk));
 }
 
+static inline bool cid_valid(u64 containerid)
+{
+   return containerid != INVALID_CID;
+}
+
 static inline bool audit_containerid_set(struct task_struct *tsk)
 {
-   return audit_get_containerid(tsk) != INVALID_CID;
+   return cid_valid(audit_get_containerid(tsk));
 }
 
 static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
diff --git a/kernel/audit.c b/kernel/audit.c
index a12f21f..b238be5 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -142,6 +142,7 @@ struct audit_net {
 kuid_t audit_sig_uid = INVALID_UID;
 pid_t  audit_sig_pid = -1;
 u32audit_sig_sid = 0;
+u64audit_sig_cid = INVALID_CID;
 
 /* Records can be lost in several ways:
0) [suppressed in audit_alloc]
@@ -1438,6 +1439,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
memcpy(sig_data->ctx, ctx, len);
security_release_secctx(ctx, len);
}
+   sig_data->cid = audit_sig_cid;
audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
 sig_data, sizeof(*sig_data) + len);
kfree(sig_data);
@@ -2051,20 +2053,22 @@ void audit_log_session_info(struct audit_buffer *ab)
 
 /*
  * audit_log_container_info - report container info
- * @tsk: task to be recorded
  * @context: task or local context for record
+ * @op: containerid string description
+ * @containerid: container ID to report
  */
-int audit_log_container_info(struct task_struct *tsk, struct audit_context 
*context)
+int audit_log_container_info(struct audit_context *context,
+ char *op, u64 containerid)
 {
struct audit_buffer *ab;
 
-   if (!audit_containerid_set(tsk))
+   if (!cid_valid(containerid))
return 0;
/* Generate AUDIT_CONTAINER_INFO with container ID */
ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER_INFO);
if (!ab)
return -ENOMEM;
-   audit_log_format(ab, "contid=%llu", audit_get_containerid(tsk));
+   audit_log_format(ab, "op=%s contid=%llu", op, containerid);
audit_log_end(ab);
return 0;
 }
diff --git a/kernel/audit.h b/kernel/audit.h
index aaa651a..743d445 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -147,6 +147,7 @@ struct audit_context {
kuid_t  target_uid;
unsigned inttarget_sessionid;
u32 target_sid;
+   u64 target_cid;
chartarget_comm[TASK_COMM_LEN];
 
struct audit_tree_refs *trees, *first_trees;
@@ -330,6 +331,7 @@ extern void audit_log_d_path_exe(struct audit_buffer *ab,
 extern pid_t audit_sig_pid;
 extern kuid_t audit_sig_uid;
 extern u32 audit_sig_sid;
+extern u64 audit_sig_cid;
 
 extern int audit_filter(int msgtype, unsigned int listtype);
 
diff --git 

[RFC PATCH ghak32 V2 13/13] debug audit: read container ID of a process

2018-03-16 Thread Richard Guy Briggs
Add support for reading the container ID from the proc filesystem.

This is a read from the proc entry of the form /proc/PID/containerid
where PID is the process ID of the task whose container ID is sought.

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

Signed-off-by: Richard Guy Briggs 
---
 fs/proc/base.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6ce4fbe..f66d1e2 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1300,6 +1300,21 @@ static ssize_t proc_sessionid_read(struct file * file, 
char __user * buf,
.llseek = generic_file_llseek,
 };
 
+static ssize_t proc_containerid_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+   struct inode *inode = file_inode(file);
+   struct task_struct *task = get_proc_task(inode);
+   ssize_t length;
+   char tmpbuf[TMPBUFLEN*2];
+
+   if (!task)
+   return -ESRCH;
+   length = scnprintf(tmpbuf, TMPBUFLEN*2, "%llu", 
audit_get_containerid(task));
+   put_task_struct(task);
+   return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
 static ssize_t proc_containerid_write(struct file *file, const char __user 
*buf,
   size_t count, loff_t *ppos)
 {
@@ -1330,6 +1345,7 @@ static ssize_t proc_containerid_write(struct file *file, 
const char __user *buf,
 }
 
 static const struct file_operations proc_containerid_operations = {
+   .read   = proc_containerid_read,
.write  = proc_containerid_write,
.llseek = generic_file_llseek,
 };
@@ -2996,7 +3012,7 @@ static int proc_pid_patch_state(struct seq_file *m, 
struct pid_namespace *ns,
 #ifdef CONFIG_AUDITSYSCALL
REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid",  S_IRUGO, proc_sessionid_operations),
-   REG("containerid", S_IWUSR, proc_containerid_operations),
+   REG("containerid", S_IWUSR|S_IRUSR, proc_containerid_operations),
 #endif
 #ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
@@ -3391,7 +3407,7 @@ static int proc_tid_comm_permission(struct inode *inode, 
int mask)
 #ifdef CONFIG_AUDITSYSCALL
REG("loginuid",  S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid",  S_IRUGO, proc_sessionid_operations),
-   REG("containerid", S_IWUSR, proc_containerid_operations),
+   REG("containerid", S_IWUSR|S_IRUSR, proc_containerid_operations),
 #endif
 #ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[RFC PATCH ghak32 V2 09/13] audit: add containerid support for config/feature/user records

2018-03-16 Thread Richard Guy Briggs
Add container ID auxiliary records to configuration change, feature set change
and user generated standalone records.

Signed-off-by: Richard Guy Briggs 
---
 kernel/audit.c   | 50 --
 kernel/auditfilter.c |  5 -
 2 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index b238be5..08662b4 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -400,8 +400,9 @@ static int audit_log_config_change(char *function_name, u32 
new, u32 old,
 {
struct audit_buffer *ab;
int rc = 0;
+   struct audit_context *context = audit_alloc_local();
 
-   ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+   ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return rc;
audit_log_format(ab, "%s=%u old=%u", function_name, new, old);
@@ -411,6 +412,8 @@ static int audit_log_config_change(char *function_name, u32 
new, u32 old,
allow_changes = 0; /* Something weird, deny request */
audit_log_format(ab, " res=%d", allow_changes);
audit_log_end(ab);
+   audit_log_container_info(context, "config", 
audit_get_containerid(current));
+   audit_free_context(context);
return rc;
 }
 
@@ -1058,7 +1061,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 
msg_type)
return err;
 }
 
-static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
+static void audit_log_common_recv_msg(struct audit_context *context,
+ struct audit_buffer **ab, u16 msg_type)
 {
uid_t uid = from_kuid(_user_ns, current_uid());
pid_t pid = task_tgid_nr(current);
@@ -1068,7 +1072,7 @@ static void audit_log_common_recv_msg(struct audit_buffer 
**ab, u16 msg_type)
return;
}
 
-   *ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+   *ab = audit_log_start(context, GFP_KERNEL, msg_type);
if (unlikely(!*ab))
return;
audit_log_format(*ab, "pid=%d uid=%u", pid, uid);
@@ -1097,11 +1101,12 @@ static void audit_log_feature_change(int which, u32 
old_feature, u32 new_feature
 u32 old_lock, u32 new_lock, int res)
 {
struct audit_buffer *ab;
+   struct audit_context *context = audit_alloc_local();
 
if (audit_enabled == AUDIT_OFF)
return;
 
-   ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE);
+   ab = audit_log_start(context, GFP_KERNEL, AUDIT_FEATURE_CHANGE);
if (!ab)
return;
audit_log_task_info(ab, current);
@@ -1109,6 +1114,8 @@ static void audit_log_feature_change(int which, u32 
old_feature, u32 new_feature
 audit_feature_names[which], !!old_feature, 
!!new_feature,
 !!old_lock, !!new_lock, res);
audit_log_end(ab);
+   audit_log_container_info(context, "feature", 
audit_get_containerid(current));
+   audit_free_context(context);
 }
 
 static int audit_set_feature(struct sk_buff *skb)
@@ -1337,13 +1344,15 @@ static int audit_receive_msg(struct sk_buff *skb, 
struct nlmsghdr *nlh)
 
err = audit_filter(msg_type, AUDIT_FILTER_USER);
if (err == 1) { /* match or error */
+   struct audit_context *context = audit_alloc_local();
+
err = 0;
if (msg_type == AUDIT_USER_TTY) {
err = tty_audit_push();
if (err)
break;
}
-   audit_log_common_recv_msg(, msg_type);
+   audit_log_common_recv_msg(context, , msg_type);
if (msg_type != AUDIT_USER_TTY)
audit_log_format(ab, " msg='%.*s'",
 AUDIT_MESSAGE_TEXT_MAX,
@@ -1359,6 +1368,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
audit_log_n_untrustedstring(ab, data, size);
}
audit_log_end(ab);
+   audit_log_container_info(context, "user",
+
audit_get_containerid(current));
+   audit_free_context(context);
}
break;
case AUDIT_ADD_RULE:
@@ -1366,9 +1378,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
return -EINVAL;
if (audit_enabled == AUDIT_LOCKED) {
-   audit_log_common_recv_msg(, AUDIT_CONFIG_CHANGE);
+   struct audit_context *context = audit_alloc_local();
+
+   

[RFC PATCH ghak32 V2 01/13] audit: add container id

2018-03-16 Thread Richard Guy Briggs
Implement the proc fs write to set the audit container ID of a process,
emitting an AUDIT_CONTAINER record to document the event.

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

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

This will produce a record such as this:
type=CONTAINER msg=audit(1519903238.968:261): op=set pid=596 uid=0 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 auid=0 tty=pts0 
ses=1 opid=596 old-contid=18446744073709551615 contid=123455 res=0

The "op" field indicates an initial set.  The "pid" to "ses" fields are
the orchestrator while the "opid" field is the object's PID, the process
being "contained".  Old and new container ID values are given in the
"contid" fields, while res indicates its success.

It is not permitted to self-set, unset or re-set the container ID.  A
child inherits its parent's container ID, but then can be set only once
after.

See: https://github.com/linux-audit/audit-kernel/issues/32

Signed-off-by: Richard Guy Briggs 
---
 fs/proc/base.c | 37 
 include/linux/audit.h  | 16 +
 include/linux/init_task.h  |  4 ++-
 include/linux/sched.h  |  1 +
 include/uapi/linux/audit.h |  2 ++
 kernel/auditsc.c   | 84 ++
 6 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 60316b5..6ce4fbe 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1299,6 +1299,41 @@ static ssize_t proc_sessionid_read(struct file * file, 
char __user * buf,
.read   = proc_sessionid_read,
.llseek = generic_file_llseek,
 };
+
+static ssize_t proc_containerid_write(struct file *file, const char __user 
*buf,
+  size_t count, loff_t *ppos)
+{
+   struct inode *inode = file_inode(file);
+   u64 containerid;
+   int rv;
+   struct task_struct *task = get_proc_task(inode);
+
+   if (!task)
+   return -ESRCH;
+   if (*ppos != 0) {
+   /* No partial writes. */
+   put_task_struct(task);
+   return -EINVAL;
+   }
+
+   rv = kstrtou64_from_user(buf, count, 10, );
+   if (rv < 0) {
+   put_task_struct(task);
+   return rv;
+   }
+
+   rv = audit_set_containerid(task, containerid);
+   put_task_struct(task);
+   if (rv < 0)
+   return rv;
+   return count;
+}
+
+static const struct file_operations proc_containerid_operations = {
+   .write  = proc_containerid_write,
+   .llseek = generic_file_llseek,
+};
+
 #endif
 
 #ifdef CONFIG_FAULT_INJECTION
@@ -2961,6 +2996,7 @@ static int proc_pid_patch_state(struct seq_file *m, 
struct pid_namespace *ns,
 #ifdef CONFIG_AUDITSYSCALL
REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid",  S_IRUGO, proc_sessionid_operations),
+   REG("containerid", S_IWUSR, proc_containerid_operations),
 #endif
 #ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
@@ -3355,6 +3391,7 @@ static int proc_tid_comm_permission(struct inode *inode, 
int mask)
 #ifdef CONFIG_AUDITSYSCALL
REG("loginuid",  S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid",  S_IRUGO, proc_sessionid_operations),
+   REG("containerid", S_IWUSR, proc_containerid_operations),
 #endif
 #ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
diff --git a/include/linux/audit.h b/include/linux/audit.h
index af410d9..fe4ba3f 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -29,6 +29,7 @@
 
 #define AUDIT_INO_UNSET ((unsigned long)-1)
 #define AUDIT_DEV_UNSET ((dev_t)-1)
+#define INVALID_CID AUDIT_CID_UNSET
 
 struct audit_sig_info {
uid_t   uid;
@@ -321,6 +322,7 @@ static inline void audit_ptrace(struct task_struct *t)
 extern int auditsc_get_stamp(struct audit_context *ctx,
  struct timespec64 *t, unsigned int *serial);
 extern int audit_set_loginuid(kuid_t loginuid);
+extern int audit_set_containerid(struct task_struct *tsk, u64 containerid);
 
 static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
 {
@@ -332,6 +334,11 @@ static inline unsigned int audit_get_sessionid(struct 
task_struct *tsk)
return tsk->sessionid;
 }
 
+static inline u64 audit_get_containerid(struct task_struct *tsk)
+{
+   return tsk->containerid;
+}
+
 extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
 extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, 
umode_t mode);
 extern void __audit_bprm(struct linux_binprm *bprm);
@@ -517,6 +524,10 @@ static 

[RFC PATCH ghak32 V2 04/13] audit: add containerid filtering

2018-03-16 Thread Richard Guy Briggs
Implement container ID filtering using the AUDIT_CONTAINERID field name
to send an 8-character string representing a u64 since the value field
is only u32.

Sending it as two u32 was considered, but gathering and comparing two
fields was more complex.

The feature indicator is AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER.

This requires support from userspace to be useful.
See: https://github.com/linux-audit/audit-userspace/issues/40
Signed-off-by: Richard Guy Briggs 
---
 include/linux/audit.h  |  1 +
 include/uapi/linux/audit.h |  5 -
 kernel/audit.h |  1 +
 kernel/auditfilter.c   | 47 ++
 kernel/auditsc.c   |  3 +++
 5 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 3acbe9d..f10ca1b 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -76,6 +76,7 @@ struct audit_field {
u32 type;
union {
u32 val;
+   u64 val64;
kuid_t  uid;
kgid_t  gid;
struct {
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index e83ccbd..8443a8f 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -262,6 +262,7 @@
 #define AUDIT_LOGINUID_SET 24
 #define AUDIT_SESSIONID25  /* Session ID */
 #define AUDIT_FSTYPE   26  /* FileSystem Type */
+#define AUDIT_CONTAINERID  27  /* Container ID */
 
/* These are ONLY useful when checking
 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -342,6 +343,7 @@ enum {
 #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER  0x0010
 #define AUDIT_FEATURE_BITMAP_LOST_RESET0x0020
 #define AUDIT_FEATURE_BITMAP_FILTER_FS 0x0040
+#define AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER0x0080
 
 #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \
  AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \
@@ -349,7 +351,8 @@ enum {
  AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \
  AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \
  AUDIT_FEATURE_BITMAP_LOST_RESET | \
- AUDIT_FEATURE_BITMAP_FILTER_FS)
+ AUDIT_FEATURE_BITMAP_FILTER_FS | \
+ AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER)
 
 /* deprecated: AUDIT_VERSION_* */
 #define AUDIT_VERSION_LATEST   AUDIT_FEATURE_BITMAP_ALL
diff --git a/kernel/audit.h b/kernel/audit.h
index 214e149..aaa651a 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -234,6 +234,7 @@ static inline int audit_hash_ino(u32 ino)
 
 extern int audit_match_class(int class, unsigned syscall);
 extern int audit_comparator(const u32 left, const u32 op, const u32 right);
+extern int audit_comparator64(const u64 left, const u32 op, const u64 right);
 extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
 extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
 extern int parent_len(const char *path);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index d7a807e..c4c8746 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -410,6 +410,7 @@ static int audit_field_valid(struct audit_entry *entry, 
struct audit_field *f)
/* FALL THROUGH */
case AUDIT_ARCH:
case AUDIT_FSTYPE:
+   case AUDIT_CONTAINERID:
if (f->op != Audit_not_equal && f->op != Audit_equal)
return -EINVAL;
break;
@@ -584,6 +585,14 @@ static struct audit_entry *audit_data_to_entry(struct 
audit_rule_data *data,
}
entry->rule.exe = audit_mark;
break;
+   case AUDIT_CONTAINERID:
+   if (f->val != sizeof(u64))
+   goto exit_free;
+   str = audit_unpack_string(, , f->val);
+   if (IS_ERR(str))
+   goto exit_free;
+   f->val64 = ((u64 *)str)[0];
+   break;
}
}
 
@@ -666,6 +675,11 @@ static struct audit_rule_data *audit_krule_to_data(struct 
audit_krule *krule)
data->buflen += data->values[i] =
audit_pack_string(, 
audit_mark_path(krule->exe));
break;
+   case AUDIT_CONTAINERID:
+   data->buflen += data->values[i] = sizeof(u64);
+   for (i = 0; i < sizeof(u64); i++)
+   ((char *)bufp)[i] = ((char *)>val64)[i];
+   break;
case 

[RFC PATCH ghak32 V2 03/13] audit: log container info of syscalls

2018-03-16 Thread Richard Guy Briggs
Create a new audit record AUDIT_CONTAINER_INFO to document the container
ID 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=c03e syscall=257 
success=yes exit=3 a0=ff9c 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= cap_fi= 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= 
cap_fi= cap_fe=0 cap_fver=0
type=PROCTITLE msg=audit(1519924845.499:257): 
proctitle=62617368002D6300736C65657020313B206563686F2074657374203E202F746D702F746D70636F6E7461696E65726964
type=CONTAINER_INFO msg=audit(1519924845.499:257): op=task contid=123458

See: https://github.com/linux-audit/audit-kernel/issues/32
Signed-off-by: Richard Guy Briggs 
---
 include/linux/audit.h  |  5 +
 include/uapi/linux/audit.h |  1 +
 kernel/audit.c | 20 
 kernel/auditsc.c   |  2 ++
 4 files changed, 28 insertions(+)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index fe4ba3f..3acbe9d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -154,6 +154,8 @@ extern void audit_log_link_denied(const char 
*operation,
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk);
+extern int audit_log_container_info(struct task_struct *tsk,
+struct audit_context *context);
 
 extern int audit_update_lsm_rules(void);
 
@@ -205,6 +207,9 @@ static inline int audit_log_task_context(struct 
audit_buffer *ab)
 static inline void audit_log_task_info(struct audit_buffer *ab,
   struct task_struct *tsk)
 { }
+static inline int audit_log_container_info(struct task_struct *tsk,
+   struct audit_context *context);
+{ }
 #define audit_enabled 0
 #endif /* CONFIG_AUDIT */
 
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 921a71f..e83ccbd 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -115,6 +115,7 @@
 #define AUDIT_REPLACE  1329/* Replace auditd if this packet 
unanswerd */
 #define AUDIT_KERN_MODULE  1330/* Kernel Module events */
 #define AUDIT_FANOTIFY 1331/* Fanotify access decision */
+#define AUDIT_CONTAINER_INFO   1332/* Container ID information */
 
 #define AUDIT_AVC  1400/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR  1401/* Internal SE Linux Errors */
diff --git a/kernel/audit.c b/kernel/audit.c
index 3f2f143..a12f21f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2049,6 +2049,26 @@ void audit_log_session_info(struct audit_buffer *ab)
audit_log_format(ab, " auid=%u ses=%u", auid, sessionid);
 }
 
+/*
+ * audit_log_container_info - report container info
+ * @tsk: task to be recorded
+ * @context: task or local context for record
+ */
+int audit_log_container_info(struct task_struct *tsk, struct audit_context 
*context)
+{
+   struct audit_buffer *ab;
+
+   if (!audit_containerid_set(tsk))
+   return 0;
+   /* Generate AUDIT_CONTAINER_INFO with container ID */
+   ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER_INFO);
+   if (!ab)
+   return -ENOMEM;
+   audit_log_format(ab, "contid=%llu", audit_get_containerid(tsk));
+   audit_log_end(ab);
+   return 0;
+}
+
 void audit_log_key(struct audit_buffer *ab, char *key)
 {
audit_log_format(ab, " key=");
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index a6b0a52..65be110 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1453,6 +1453,8 @@ static void audit_log_exit(struct audit_context *context, 
struct task_struct *ts
 
audit_log_proctitle(tsk, context);
 
+   audit_log_container_info(tsk, context);
+
/* Send end of event record to help user space know we are finished */
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
if (ab)
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


[RFC PATCH ghak32 V2 02/13] audit: check children and threading before allowing containerid

2018-03-16 Thread Richard Guy Briggs
Check if a task has existing children or co-threads and refuse to set
the container ID if either are present.  Failure to check this could
permit games where a child scratches its parent's back to work around
inheritance and double-setting policy.

Signed-off-by: Richard Guy Briggs 
---
 kernel/auditsc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 29c8482..a6b0a52 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2087,6 +2087,10 @@ static int audit_set_containerid_perm(struct task_struct 
*task, u64 containerid)
/* if we don't have caps, reject */
if (!capable(CAP_AUDIT_CONTROL))
return -EPERM;
+   /* if task has children or is not single-threaded, deny */
+   if (!list_empty(>children) ||
+   !(thread_group_leader(task) && thread_group_empty(task)))
+   return -EPERM;
/* if containerid is unset, allow */
if (!audit_containerid_set(task))
return 0;
-- 
1.8.3.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit