Add support to be able to set a capability to allow a task to set the audit container identifier of descendants. See: https://github.com/linux-audit/audit-userspace/issues/51 See: https://github.com/linux-audit/audit-kernel/issues/90 See: https://github.com/linux-audit/audit-testsuite/issues/64 See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID Add the audit_get_capcontid() and audit_set_capcontid() calls analogous to CAP_AUDIT_CONTROL for descendant user namespaces. Signed-off-by: Richard Guy Briggs <rgb@xxxxxxxxxx> --- docs/Makefile.am | 1 + lib/libaudit.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/libaudit.h | 14 +++++++++ lib/msg_typetab.h | 2 ++ lib/netlink.c | 4 +++ 5 files changed, 106 insertions(+) diff --git a/docs/Makefile.am b/docs/Makefile.am index 821182315806..8b0e5c2c3730 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -29,6 +29,7 @@ auditd.conf.5 auditd-plugins.5 \ audit_delete_rule_data.3 audit_detect_machine.3 \ audit_encode_nv_string.3 audit_getloginuid.3 \ audit_get_reply.3 audit_get_session.3 audit_get_containerid.3 audit_set_containerid.3 \ +audit_get_capcontid.3 audit_set_capcontid.3 \ audit_log_acct_message.3 audit_log_user_avc_message.3 \ audit_log_user_command.3 audit_log_user_comm_message.3 \ audit_log_user_message.3 audit_log_semanage_message.3 \ diff --git a/lib/libaudit.c b/lib/libaudit.c index 62e1a2a64ee5..08998610c66a 100644 --- a/lib/libaudit.c +++ b/lib/libaudit.c @@ -1026,6 +1026,91 @@ uint32_t audit_get_session(void) } /* + * This function will retrieve the capability container identifier or -2 if + * there is an error. + */ +uint32_t audit_get_capcontid(pid_t pid) +{ + if ((audit_get_features() & AUDIT_FEATURE_BITMAP_CONTAINERID) == 0) { + return -2; + } else { + struct audit_reply rep; + int i; + int timeout = 40; /* tenths of seconds */ + struct pollfd pfd[1]; + int fd = audit_open(); + struct audit_capcontid_status cs; + int rc; + + if (fd < 0) { + audit_msg(audit_priority(errno), "Error openning get capcontid req (%s)", strerror(-rc)); + return -2; + } + cs.pid = pid; + rc = audit_send(fd, AUDIT_GET_CONTID, &cs, sizeof(cs)); + if (rc < 0 && rc != -EINVAL) { + audit_close(fd); + audit_msg(audit_priority(errno), "Error sending set capcontid req (%s)", strerror(-rc)); + return -2; + } + pfd[0].fd = fd; + pfd[0].events = POLLIN; + + for (i = 0; i < timeout; i++) { + do { + rc = poll(pfd, 1, 100); + } while (rc < 0 && errno == EINTR); + rc = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING,0); + if (rc > 0) { + /* If we get done or error, break out */ + if (rep.type == NLMSG_DONE || + rep.type == NLMSG_ERROR) + break; + + /* If its not get_contid, keep looping */ + if (rep.type != AUDIT_GET_CAPCONTID) + continue; + + /* Found it... */ + audit_close(fd); + if (rep.capcontid->pid == pid) + return rep.capcontid->cap; + else + return -2; + } + } + audit_close(fd); + return -2; + } +} + +/* + * This function returns 0 on success and 1 on failure + */ +int audit_set_capcontid(pid_t pid, uint32_t capcontid) +{ + if ((audit_get_features() & AUDIT_FEATURE_BITMAP_CONTAINERID) == 0) { + return -2; + } else { + int rc; + int seq; + int fd = audit_open(); + struct audit_capcontid_status cs = { pid, capcontid }; + + if (fd < 0) { + audit_msg(audit_priority(errno), "Error openning set capcontid req (%s)", strerror(-rc)); + return 1; + } + rc = audit_send(fd, AUDIT_SET_CAPCONTID, &cs, sizeof(cs)); + if (rc < 0) { + audit_msg(audit_priority(errno), "Error sending set capcontid request (%s)", strerror(-rc)); + return 1; + } + return 0; + } +} + +/* * This function will retrieve the audit container identifier or -2 if * there is an error. */ diff --git a/lib/libaudit.h b/lib/libaudit.h index 717724e8fbbb..8067ef30f427 100644 --- a/lib/libaudit.h +++ b/lib/libaudit.h @@ -275,6 +275,14 @@ extern "C" { #define AUDIT_GET_SESSIONID 1026 /* get current process sessionid */ #endif +#ifndef AUDIT_GET_CAPCONTID +#define AUDIT_GET_CAPCONTID 1027 /* get contid of specified pid */ +#endif + +#ifndef AUDIT_SET_CAPCONTID +#define AUDIT_SET_CAPCONTID 1028 /* set contid of specified pid */ +#endif + #ifndef AUDIT_MMAP #define AUDIT_MMAP 1323 /* Descriptor and flags in mmap */ #endif @@ -532,6 +540,11 @@ struct audit_message { // internal - forward declaration struct daemon_conf; +struct audit_capcontid_status { + pid_t pid; + uint32_t cap; +}; + struct audit_cont_status { pid_t pid; uint64_t id; @@ -559,6 +572,7 @@ struct audit_reply { #endif #ifdef AUDIT_FEATURE_BITMAP_CONTAINERID struct audit_cont_status *cont; + struct audit_capcontid_status *capcontid; #endif }; }; diff --git a/lib/msg_typetab.h b/lib/msg_typetab.h index 9f2b137dc7f8..f510e9790ea4 100644 --- a/lib/msg_typetab.h +++ b/lib/msg_typetab.h @@ -50,6 +50,8 @@ _S(AUDIT_LOGIN, "LOGIN" ) //_S(AUDIT_GET_LOGINUID, "GET_LOGINUID" ) //_S(AUDIT_SET_LOGINUID, "SET_LOGINUID" ) //_S(AUDIT_GET_SESSIONID, "GET_SESSIONID" ) +//_S(AUDIT_GET_CAPCONTID, "GET_CAPCONTID" ) +_S(AUDIT_SET_CAPCONTID, "SET_CAPCONTID" ) _S(AUDIT_CONTAINER_OP, "CONTAINER_OP" ) _S(AUDIT_USER_AUTH, "USER_AUTH" ) _S(AUDIT_USER_ACCT, "USER_ACCT" ) diff --git a/lib/netlink.c b/lib/netlink.c index d177b865a79e..d378b32e0ff6 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -154,6 +154,7 @@ static int adjust_reply(struct audit_reply *rep, int len) #endif #ifdef AUDIT_FEATURE_BITMAP_CONTAINERID rep->cont = NULL; + rep->capcontid = NULL; #endif if (!NLMSG_OK(rep->nlh, (unsigned int)len)) { if (len == sizeof(rep->msg)) { @@ -201,6 +202,9 @@ static int adjust_reply(struct audit_reply *rep, int len) case AUDIT_SIGNAL_INFO2: rep->signal_info2 = NLMSG_DATA(rep->nlh); break; + case AUDIT_GET_CAPCONTID: + rep->capcontid = NLMSG_DATA(rep->nlh); + break; case AUDIT_GET_CONTID: rep->cont = NLMSG_DATA(rep->nlh); break; -- 1.8.3.1 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/containers