From 7085a3c95d8c76cc6a402def82cce0f7654764cd Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Tue, 27 Feb 2018 05:02:11 -0500 Subject: [PATCH] auditctl: add support for AUDIT_CONTID filter 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 AUDIT_CONTID field to filter based on audit container identifier. This field is specified with the "contid" field name on the command line. 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/91 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 --- docs/auditctl.8 | 3 +++ lib/fieldtab.h | 1 + lib/libaudit.c | 35 +++++++++++++++++++++++++++++++++++ lib/libaudit.h | 7 +++++++ src/auditctl-listing.c | 21 +++++++++++++++++++++ 5 files changed, 67 insertions(+) diff --git a/docs/auditctl.8 b/docs/auditctl.8 index 6606077c2..daed435f0 100644 --- a/docs/auditctl.8 +++ b/docs/auditctl.8 @@ -216,6 +216,9 @@ Address family number as found in /usr/include/bits/socket.h. For example, IPv4 .B sessionid User's login session ID .TP +.B contid +Process' audit container ID +.TP .B subj_user Program's SE Linux User .TP diff --git a/lib/fieldtab.h b/lib/fieldtab.h index b597cafb2..e0a49d015 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_CONTID, "contid" ) _S(AUDIT_DEVMAJOR, "devmajor" ) _S(AUDIT_DEVMINOR, "devminor" ) diff --git a/lib/libaudit.c b/lib/libaudit.c index 864821e5e..2e7b18a70 100644 --- a/lib/libaudit.c +++ b/lib/libaudit.c @@ -1763,6 +1763,41 @@ int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair, if (rule->values[rule->field_count] >= AF_MAX) return -EAU_FIELDVALTOOBIG; break; + case AUDIT_CONTID: { + unsigned long long val; + + if ((audit_get_features() & + AUDIT_FEATURE_BITMAP_CONTAINERID) == 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; + } + rule = *rulep; + *(unsigned long long *)(&rule->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 9c2f6d424..a249463a0 100644 --- a/lib/libaudit.h +++ b/lib/libaudit.h @@ -362,6 +362,9 @@ extern "C" { #ifndef AUDIT_FEATURE_BITMAP_FILTER_FS #define AUDIT_FEATURE_BITMAP_FILTER_FS 0x00000040 #endif +#ifndef AUDIT_FEATURE_BITMAP_CONTAINERID +#define AUDIT_FEATURE_BITMAP_CONTAINERID 0x00000080 +#endif /* Defines for interfield comparison update */ #ifndef AUDIT_OBJ_UID @@ -388,6 +391,10 @@ extern "C" { #define AUDIT_FSTYPE 26 #endif +#ifndef AUDIT_CONTID +#define AUDIT_CONTID 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 6eb3b56bb..652867eb2 100644 --- a/src/auditctl-listing.c +++ b/src/auditctl-listing.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "auditctl-listing.h" #include "private.h" #include "auditctl-llist.h" @@ -460,6 +461,26 @@ static void print_rule(const struct audit_rule_data *r) audit_operator_to_symbol(op), audit_fstype_to_name( r->values[i])); + } else if (field == AUDIT_CONTID) { + unsigned long long val; + + if (r->values[i] == sizeof(unsigned long long)) { + val = *(unsigned long long *)(&r->buf[boffset]); + + if (val != ULLONG_MAX) + printf(" -F %s%s%llu", name, + audit_operator_to_symbol(op), + val); + else + printf(" -F %s%s%s", name, + audit_operator_to_symbol(op), + "unset"); + } else { + printf(" -F %s%s%s", name, + audit_operator_to_symbol(op), + "inval"); + } + boffset += r->values[i]; } else { // The default is signed decimal printf(" -F %s%s%d", name,