Skip to content

Commit

Permalink
libaudit: add support to get and set capcontid on a task
Browse files Browse the repository at this point in the history
Add support to be able to set a capability to allow a task to set the
audit container identifier of descendants.

See: linux-audit#51
See: linux-audit/audit-kernel#90
See: linux-audit/audit-testsuite#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@redhat.com>
  • Loading branch information
rgbriggs committed Jun 27, 2020
1 parent e49817c commit c7dc160
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions auparse/normalize.c
Expand Up @@ -911,6 +911,7 @@ static const char *normalize_determine_evkind(int type)
case AUDIT_FEATURE_CHANGE ... AUDIT_REPLACE:
case AUDIT_USER_DEVICE:
case AUDIT_SOFTWARE_UPDATE:
case AUDIT_SET_CAPCONTID:
kind = NORM_EVTYPE_CONFIG;
break;
case AUDIT_SECCOMP:
Expand Down
1 change: 1 addition & 0 deletions auparse/normalize_record_map.h
Expand Up @@ -26,6 +26,7 @@
_S(AUDIT_USER, "sent-message")
_S(AUDIT_LOGIN, "changed-login-id-to")
_S(AUDIT_CONTAINER_OP, "changed-container-id-to")
_S(AUDIT_SET_CAPCONTID, "set-capcontid-to")
_S(AUDIT_USER_AUTH, "authenticated")
_S(AUDIT_USER_ACCT, "was-authorized")
_S(AUDIT_USER_MGMT, "modified-user-account")
Expand Down
1 change: 1 addition & 0 deletions docs/Makefile.am
Expand Up @@ -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_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 \
Expand Down
25 changes: 25 additions & 0 deletions docs/audit_get_capcontid.3
@@ -0,0 +1,25 @@
.TH "AUDIT_GET_CAPCONTID" "26" "Aug 2019" "Red Hat" "Linux Audit API"
.SH NAME
audit_get_capcontid \- Get a program's capability container id value
.SH SYNOPSIS
.B #include <libaudit.h>
.sp
int audit_get_capcontid(pid_t pid);

.SH DESCRIPTION
This function returns the pid task's audit capability container identifier attribute.

.SH "RETURN VALUE"

This function returns the audit capability container identifier value if it is implemented. It will return a \-1 if the audit capability container identifier is unavailable.

.SH "ERRORS"

This function returns \-2 on failure. Additionally, in the event of a real error, errno would be set. The function can set errno based on failures of open, read, or strtoull.

.SH "SEE ALSO"

.BR audit_set_capcontid (3).

.SH AUTHOR
Richard Guy Briggs
24 changes: 24 additions & 0 deletions docs/audit_set_capcontid.3
@@ -0,0 +1,24 @@
.TH "AUDIT_SET_CAPCONTID" "26" "Aug 2019" "Red Hat" "Linux Audit API"
.SH NAME
audit_set_capcontid \- Set a program's capability container id value
.SH SYNOPSIS
.B #include <libaudit.h>
.sp
int audit_set_capcontid(pid_t pid, uint32_t capcontid);

.SH "DESCRIPTION"

This function sets the pid task's attribute capability container id with the value of capcontid. The capcontid value may only be set by programs with the CAP_AUDIT_CONTROL capability in the initial user namespace or with capcontid. This normally means the root account or root in a container.
.sp
The capcontid value is part of the task structure and is inheritted by child processes within a user namespace. It is used to enable the capability to set container identifier of a child task in a descendent user namespace. Container orchestrator/engines should set this value only on children it wishes to be able to set audit container identifiers.

.SH "RETURN VALUE"

This function returns 0 on success and non-zero otherwise.

.SH "SEE ALSO"

.BR audit_get_capcontid (3).

.SH AUTHOR
Richard Guy Briggs
74 changes: 74 additions & 0 deletions lib/libaudit.c
Expand Up @@ -990,6 +990,80 @@ uint32_t audit_get_session(void)
return ses;
}

/*
* 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 {
int capcontid;
int len, in;
char buf[16], fnbuf[48];

errno = 0;
snprintf(fnbuf, sizeof(fnbuf), "/proc/%d/audit_capcontainerid", pid);
in = open(fnbuf, O_NOFOLLOW|O_RDONLY);
if (in < 0)
return -2;
do {
len = read(in, buf, sizeof(buf));
} while (len < 0 && errno == EINTR);
close(in);
if (len < 0 || len >= sizeof(buf))
return -2;
buf[len] = 0;
errno = 0;
capcontid = strtol(buf, 0, 10);
if (errno)
return -2;
else
return capcontid;
}
}

/*
* 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 {
char capcontidbuf[16], fnbuf[48];
int o, count, rc = 0;

errno = 0;
count = snprintf(capcontidbuf, sizeof(capcontidbuf), "%u", capcontid);
snprintf(fnbuf, sizeof(fnbuf), "/proc/%d/audit_capcontainerid", pid);
o = open(fnbuf, O_NOFOLLOW|O_WRONLY|O_TRUNC);
if (o >= 0) {
int block, offset = 0;

while (count > 0) {
block = write(o, &capcontidbuf[offset], (unsigned)count);

if (block < 0) {
if (errno == EINTR)
continue;
audit_msg(LOG_ERR, "Error writing capcontid");
close(o);
return 1;
}
offset += block;
count -= block;
}
close(o);
} else {
audit_msg(LOG_ERR, "Error opening %s", fnbuf);
rc = 1;
}
return rc;
}
}

/*
* This function will retrieve the audit container identifier or -2 if
* there is an error.
Expand Down
4 changes: 4 additions & 0 deletions lib/libaudit.h
Expand Up @@ -255,6 +255,10 @@ extern "C" {
#define AUDIT_SIGNAL_INFO2 1021 /* auditd signal sender info */
#endif

#ifndef AUDIT_SET_CAPCONTID
#define AUDIT_SET_CAPCONTID 1022 /* set capcontid of specified pid */
#endif

#ifndef AUDIT_MMAP
#define AUDIT_MMAP 1323 /* Descriptor and flags in mmap */
#endif
Expand Down
1 change: 1 addition & 0 deletions lib/msg_typetab.h
Expand Up @@ -46,6 +46,7 @@ _S(AUDIT_LOGIN, "LOGIN" )
//_S(AUDIT_GET_FEATURE, "GET_FEATURE" )
//_S(AUDIT_SIGNAL_INFO2, "SIGNAL_INFO2" )
_S(AUDIT_CONTAINER_OP, "CONTAINER_OP" )
_S(AUDIT_SET_CAPCONTID, "SET_CAPCONTID" )
_S(AUDIT_USER_AUTH, "USER_AUTH" )
_S(AUDIT_USER_ACCT, "USER_ACCT" )
_S(AUDIT_USER_MGMT, "USER_MGMT" )
Expand Down
1 change: 1 addition & 0 deletions lib/netlink.c
Expand Up @@ -186,6 +186,7 @@ static int adjust_reply(struct audit_reply *rep, int len)
case AUDIT_USER:
case AUDIT_LOGIN:
case AUDIT_CONTAINER_OP:
case AUDIT_SET_CAPCONTID:
case AUDIT_KERNEL:
case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
Expand Down
2 changes: 2 additions & 0 deletions src/ausearch-lol.c
Expand Up @@ -250,6 +250,8 @@ static void check_events(lol *lo, time_t sec)
(cur->l->e.type > AUDIT_LOGIN &&
cur->l->e.type < AUDIT_CONTAINER_OP ) ||
(cur->l->e.type > AUDIT_CONTAINER_OP &&
cur->l->e.type < AUDIT_SET_CAPCONTID ) ||
(cur->l->e.type > AUDIT_SET_CAPCONTID &&
cur->l->e.type < AUDIT_FIRST_EVENT ) ||
cur->l->e.type == AUDIT_PROCTITLE ||
(cur->l->e.type >= AUDIT_MAC_UNLBL_ALLOW &&
Expand Down
1 change: 1 addition & 0 deletions src/ausearch-parse.c
Expand Up @@ -192,6 +192,7 @@ int extract_search_items(llist *l)
case AUDIT_MMAP:
case AUDIT_PROCTITLE:
case AUDIT_REPLACE...AUDIT_BPF:
case AUDIT_SET_CAPCONTID:
// Nothing to parse
break;
case AUDIT_NETFILTER_CFG:
Expand Down

0 comments on commit c7dc160

Please sign in to comment.