diff options
Diffstat (limited to 'framework/src/audit/auparse/interpret.c')
-rw-r--r-- | framework/src/audit/auparse/interpret.c | 2651 |
1 files changed, 0 insertions, 2651 deletions
diff --git a/framework/src/audit/auparse/interpret.c b/framework/src/audit/auparse/interpret.c deleted file mode 100644 index e8f82f92..00000000 --- a/framework/src/audit/auparse/interpret.c +++ /dev/null @@ -1,2651 +0,0 @@ -/* -* interpret.c - Lookup values to something more readable -* Copyright (c) 2007-09,2011-15 Red Hat Inc., Durham, North Carolina. -* All Rights Reserved. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2.1 of the License, or (at your option) any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* Authors: -* Steve Grubb <sgrubb@redhat.com> -*/ - -#include "config.h" -#include "nvlist.h" -#include "nvpair.h" -#include "libaudit.h" -#include "internal.h" -#include "interpret.h" -#include "auparse-idata.h" -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <pwd.h> -#include <grp.h> -#include <sys/stat.h> -#include <linux/net.h> -#include <netdb.h> -#include <sys/un.h> -#include <linux/ax25.h> -#include <linux/atm.h> -#include <linux/x25.h> -#include <linux/if.h> // FIXME: remove when ipx.h is fixed -#include <linux/ipx.h> -#include <linux/capability.h> -#include <sys/personality.h> -#include <sys/prctl.h> -#include <sched.h> -#include "auparse-defs.h" -#include "gen_tables.h" - -#if !HAVE_DECL_ADDR_NO_RANDOMIZE -# define ADDR_NO_RANDOMIZE 0x0040000 -#endif - -/* This is from asm/ipc.h. Copying it for now as some platforms - * have broken headers. */ -#define SEMOP 1 -#define SEMGET 2 -#define SEMCTL 3 -#define SEMTIMEDOP 4 -#define MSGSND 11 -#define MSGRCV 12 -#define MSGGET 13 -#define MSGCTL 14 -#define SHMAT 21 -#define SHMDT 22 -#define SHMGET 23 -#define SHMCTL 24 -#define DIPC 25 - -#include "captabs.h" -#include "clone-flagtabs.h" -#include "epoll_ctls.h" -#include "famtabs.h" -#include "fcntl-cmdtabs.h" -#include "flagtabs.h" -#include "ipctabs.h" -#include "ipccmdtabs.h" -#include "mmaptabs.h" -#include "mounttabs.h" -#include "open-flagtabs.h" -#include "persontabs.h" -#include "prottabs.h" -#include "ptracetabs.h" -#include "recvtabs.h" -#include "rlimittabs.h" -#include "seektabs.h" -#include "socktabs.h" -#include "socktypetabs.h" -#include "signaltabs.h" -#include "clocktabs.h" -#include "typetabs.h" -#include "nfprototabs.h" -#include "icmptypetabs.h" -#include "seccomptabs.h" -#include "accesstabs.h" -#include "prctl_opttabs.h" -#include "schedtabs.h" -#include "shm_modetabs.h" -#include "sockoptnametabs.h" -#include "sockleveltabs.h" -#include "ipoptnametabs.h" -#include "ip6optnametabs.h" -#include "tcpoptnametabs.h" -#include "pktoptnametabs.h" -#include "umounttabs.h" -#include "ioctlreqtabs.h" - -typedef enum { AVC_UNSET, AVC_DENIED, AVC_GRANTED } avc_t; -typedef enum { S_UNSET=-1, S_FAILED, S_SUCCESS } success_t; - -static const char *print_signals(const char *val, unsigned int base); -static auparse_esc_t escape_mode = AUPARSE_ESC_TTY; - -/* - * This function will take a pointer to a 2 byte Ascii character buffer and - * return the actual hex value. - */ -static unsigned char x2c(const unsigned char *buf) -{ - static const char AsciiArray[17] = "0123456789ABCDEF"; - char *ptr; - unsigned char total=0; - - ptr = strchr(AsciiArray, (char)toupper(buf[0])); - if (ptr) - total = (unsigned char)(((ptr-AsciiArray) & 0x0F)<<4); - ptr = strchr(AsciiArray, (char)toupper(buf[1])); - if (ptr) - total += (unsigned char)((ptr-AsciiArray) & 0x0F); - - return total; -} - -// Check if any characters need tty escaping. Returns how many found. -static unsigned int need_tty_escape(const unsigned char *s, unsigned int len) -{ - unsigned int i = 0, cnt = 0; - while (i < len) { - if (s[i] < 32) - cnt++; - i++; - } - return cnt; -} - -// TTY escaping s string into dest. -static void tty_escape(const char *s, char *dest, unsigned int len) -{ - unsigned int i = 0, j = 0; - while (i < len) { - if ((unsigned char)s[i] < 32) { - dest[j++] = ('\\'); - dest[j++] = ('0' + ((s[i] & 0300) >> 6)); - dest[j++] = ('0' + ((s[i] & 0070) >> 3)); - dest[j++] = ('0' + (s[i] & 0007)); - } else - dest[j++] = s[i]; - i++; - } -} - -static const char sh_set[] = "\"'`$\\"; -static unsigned int need_shell_escape(const char *s, unsigned int len) -{ - unsigned int i = 0, cnt = 0; - while (i < len) { - if (s[i] < 32) - cnt++; - else if (strchr(sh_set, s[i])) - cnt++; - i++; - } - return cnt; -} - -static void shell_escape(const char *s, char *dest, unsigned int len) -{ - unsigned int i = 0, j = 0; - while (i < len) { - if ((unsigned char)s[i] < 32) { - dest[j++] = ('\\'); - dest[j++] = ('0' + ((s[i] & 0300) >> 6)); - dest[j++] = ('0' + ((s[i] & 0070) >> 3)); - dest[j++] = ('0' + (s[i] & 0007)); - } else if (strchr(sh_set, s[i])) { - dest[j++] = ('\\'); - dest[j++] = s[i]; - } else - dest[j++] = s[i]; - i++; - } -} - -static const char quote_set[] = ";'\"`#$&*?[]<>{}\\"; -static unsigned int need_shell_quote_escape(const unsigned char *s, unsigned int len) -{ - unsigned int i = 0, cnt = 0; - while (i < len) { - if (s[i] < 32) - cnt++; - else if (strchr(quote_set, s[i])) - cnt++; - i++; - } - return cnt; -} - -static void shell_quote_escape(const char *s, char *dest, unsigned int len) -{ - unsigned int i = 0, j = 0; - while (i < len) { - if ((unsigned char)s[i] < 32) { - dest[j++] = ('\\'); - dest[j++] = ('0' + ((s[i] & 0300) >> 6)); - dest[j++] = ('0' + ((s[i] & 0070) >> 3)); - dest[j++] = ('0' + (s[i] & 0007)); - } else if (strchr(quote_set, s[i])) { - dest[j++] = ('\\'); - dest[j++] = s[i]; - } else - dest[j++] = s[i]; - i++; - } -} - -/* This should return the count of what needs escaping */ -static unsigned int need_escaping(const char *s, unsigned int len) -{ - switch (escape_mode) - { - case AUPARSE_ESC_RAW: - break; - case AUPARSE_ESC_TTY: - return need_tty_escape(s, len); - case AUPARSE_ESC_SHELL: - return need_shell_escape(s, len); - case AUPARSE_ESC_SHELL_QUOTE: - return need_shell_quote_escape(s, len);; - } - return 0; -} - -static void escape(const char *s, char *dest, unsigned int len) -{ - switch (escape_mode) - { - case AUPARSE_ESC_RAW: - return; - case AUPARSE_ESC_TTY: - return tty_escape(s, dest, len); - case AUPARSE_ESC_SHELL: - return shell_escape(s, dest, len); - case AUPARSE_ESC_SHELL_QUOTE: - return shell_quote_escape(s, dest, len); - } -} - -int set_escape_mode(auparse_esc_t mode) -{ - if (mode < 0 || mode > AUPARSE_ESC_SHELL_QUOTE) - return 1; - escape_mode = mode; - return 0; -} -hidden_def(set_escape_mode) - -static int is_hex_string(const char *str) -{ - while (*str) { - if (!isxdigit(*str)) - return 0; - str++; - } - return 1; -} - -/* returns a freshly malloc'ed and converted buffer */ -char *au_unescape(char *buf) -{ - int len, i; - char saved, *str, *ptr = buf; - - /* Find the end of the name */ - if (*ptr == '(') { - ptr = strchr(ptr, ')'); - if (ptr == NULL) - return NULL; - else - ptr++; - } else { - while (isxdigit(*ptr)) - ptr++; - } - saved = *ptr; - *ptr = 0; - str = strdup(buf); - *ptr = saved; - - /* See if its '(null)' from the kernel */ - if (*buf == '(') - return str; - - /* We can get away with this since the buffer is 2 times - * bigger than what we are putting there. - */ - len = strlen(str); - if (len < 2) { - free(str); - return NULL; - } - ptr = str; - for (i=0; i<len; i+=2) { - *ptr = x2c((unsigned char *)&str[i]); - ptr++; - } - *ptr = 0; - return str; -} - -static const char *success[3]= { "unset", "no", "yes" }; -static const char *aulookup_success(int s) -{ - switch (s) - { - default: - return success[0]; - break; - case S_FAILED: - return success[1]; - break; - case S_SUCCESS: - return success[2]; - break; - } -} - -static nvpair uid_nvl; -static int uid_list_created=0; -static const char *aulookup_uid(uid_t uid, char *buf, size_t size) -{ - char *name = NULL; - int rc; - - if (uid == -1) { - snprintf(buf, size, "unset"); - return buf; - } - - // Check the cache first - if (uid_list_created == 0) { - nvpair_create(&uid_nvl); - nvpair_clear(&uid_nvl); - uid_list_created = 1; - } - rc = nvpair_find_val(&uid_nvl, uid); - if (rc) { - name = uid_nvl.cur->name; - } else { - // Add it to cache - struct passwd *pw; - pw = getpwuid(uid); - if (pw) { - nvpnode nv; - nv.name = strdup(pw->pw_name); - nv.val = uid; - nvpair_append(&uid_nvl, &nv); - name = uid_nvl.cur->name; - } - } - if (name != NULL) - snprintf(buf, size, "%s", name); - else - snprintf(buf, size, "unknown(%d)", uid); - return buf; -} - -void aulookup_destroy_uid_list(void) -{ - if (uid_list_created == 0) - return; - - nvpair_clear(&uid_nvl); - uid_list_created = 0; -} - -static nvpair gid_nvl; -static int gid_list_created=0; -static const char *aulookup_gid(gid_t gid, char *buf, size_t size) -{ - char *name = NULL; - int rc; - - if (gid == -1) { - snprintf(buf, size, "unset"); - return buf; - } - - // Check the cache first - if (gid_list_created == 0) { - nvpair_create(&gid_nvl); - nvpair_clear(&gid_nvl); - gid_list_created = 1; - } - rc = nvpair_find_val(&gid_nvl, gid); - if (rc) { - name = gid_nvl.cur->name; - } else { - // Add it to cache - struct group *gr; - gr = getgrgid(gid); - if (gr) { - nvpnode nv; - nv.name = strdup(gr->gr_name); - nv.val = gid; - nvpair_append(&gid_nvl, &nv); - name = gid_nvl.cur->name; - } - } - if (name != NULL) - snprintf(buf, size, "%s", name); - else - snprintf(buf, size, "unknown(%d)", gid); - return buf; -} - -void aulookup_destroy_gid_list(void) -{ - if (gid_list_created == 0) - return; - - nvpair_clear(&gid_nvl); - gid_list_created = 0; -} - -static const char *print_uid(const char *val, unsigned int base) -{ - int uid; - char name[64]; - - errno = 0; - uid = strtoul(val, NULL, base); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - return strdup(aulookup_uid(uid, name, sizeof(name))); -} - -static const char *print_gid(const char *val, unsigned int base) -{ - int gid; - char name[64]; - - errno = 0; - gid = strtoul(val, NULL, base); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - return strdup(aulookup_gid(gid, name, sizeof(name))); -} - -static const char *print_arch(const char *val, unsigned int machine) -{ - const char *ptr; - char *out; - - if (machine > MACH_AARCH64) { - unsigned int ival; - - errno = 0; - ival = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s) ", val) < 0) - out = NULL; - return out; - } - machine = audit_elf_to_machine(ival); - } - if ((int)machine < 0) { - if (asprintf(&out, "unknown elf type(%s)", val) < 0) - out = NULL; - return out; - } - ptr = audit_machine_to_name(machine); - if (ptr) - return strdup(ptr); - else { - if (asprintf(&out, "unknown machine type(%d)", machine) < 0) - out = NULL; - return out; - } -} - -static const char *print_ipccall(const char *val, unsigned int base) -{ - int a0; - char *out; - const char *func = NULL; - - errno = 0; - a0 = strtol(val, NULL, base); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - func = ipc_i2s(a0); - if (func) - return strdup(func); - else { - if (asprintf(&out, "unknown ipccall(%s)", val) < 0) - out = NULL; - return out; - } -} - -static const char *print_socketcall(const char *val, unsigned int base) -{ - int a0; - char *out; - const char *func = NULL; - - errno = 0; - a0 = strtol(val, NULL, base); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - func = sock_i2s(a0); - if (func) - return strdup(func); - else { - if (asprintf(&out, "unknown socketcall(%s)", val) < 0) - out = NULL; - return out; - } -} - -static const char *print_syscall(const idata *id) -{ - const char *sys; - char *out; - int machine = id->machine, syscall = id->syscall; - unsigned long long a0 = id->a0; - - if (machine < 0) - machine = audit_detect_machine(); - if (machine < 0) { - out = strdup(id->val); - return out; - } - sys = audit_syscall_to_name(syscall, machine); - if (sys) { - const char *func = NULL; - if (strcmp(sys, "socketcall") == 0) { - if ((int)a0 == a0) - func = sock_i2s(a0); - } else if (strcmp(sys, "ipc") == 0) - if ((int)a0 == a0) - func = ipc_i2s(a0); - if (func) { - if (asprintf(&out, "%s(%s)", sys, func) < 0) - out = NULL; - } else - return strdup(sys); - } else { - if (asprintf(&out, "unknown syscall(%d)", syscall) < 0) - out = NULL; - } - - return out; -} - -static const char *print_exit(const char *val) -{ - long long ival; - char *out; - - errno = 0; - ival = strtoll(val, NULL, 10); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - if (ival < 0) { - if (asprintf(&out, "%lld(%s)", ival, strerror(-ival)) < 0) - out = NULL; - return out; - } - return strdup(val); -} - -static const char *print_escaped(const char *val) -{ - const char *out; - - if (*val == '"') { - char *term; - val++; - term = strchr(val, '"'); - if (term == NULL) - return strdup(" "); - *term = 0; - out = strdup(val); - *term = '"'; - return out; -// FIXME: working here...was trying to detect (null) and handle that -// differently. The other 2 should have " around the file names. -/* } else if (*val == '(') { - char *term; - val++; - term = strchr(val, ' '); - if (term == NULL) - return; - *term = 0; - printf("%s ", val); */ - } else if (val[0] == '0' && val[1] == '0') - out = au_unescape((char *)&val[2]); // Abstract name af_unix - else - out = au_unescape((char *)val); - if (out) - return out; - return strdup(val); // Something is wrong with string, just send as is -} - -static const char *print_proctitle(const char *val) -{ - char *out = (char *)print_escaped(val); - if (*val != '"') { - size_t len = strlen(val) / 2; - const char *end = out + len; - char *ptr = out; - while ((ptr = rawmemchr(ptr, '\0'))) { - if (ptr >= end) - break; - *ptr = ' '; - ptr++; - } - } - return out; -} - -static const char *print_perm(const char *val) -{ - int ival, printed=0; - char buf[32]; - - errno = 0; - ival = strtol(val, NULL, 10); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - buf[0] = 0; - - /* The kernel treats nothing (0x00) as everything (0x0F) */ - if (ival == 0) - ival = 0x0F; - if (ival & AUDIT_PERM_READ) { - strcat(buf, "read"); - printed = 1; - } - if (ival & AUDIT_PERM_WRITE) { - if (printed) - strcat(buf, ",write"); - else - strcat(buf, "write"); - printed = 1; - } - if (ival & AUDIT_PERM_EXEC) { - if (printed) - strcat(buf, ",exec"); - else - strcat(buf, "exec"); - printed = 1; - } - if (ival & AUDIT_PERM_ATTR) { - if (printed) - strcat(buf, ",attr"); - else - strcat(buf, "attr"); - } - return strdup(buf); -} - -static const char *print_mode(const char *val, unsigned int base) -{ - unsigned int ival; - char *out, buf[48]; - const char *name; - - errno = 0; - ival = strtoul(val, NULL, base); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - // detect the file type - name = audit_ftype_to_name(ival & S_IFMT); - if (name != NULL) - strcpy(buf, name); - else { - unsigned first_ifmt_bit; - - // The lowest-valued "1" bit in S_IFMT - first_ifmt_bit = S_IFMT & ~(S_IFMT - 1); - sprintf(buf, "%03o", (ival & S_IFMT) / first_ifmt_bit); - } - - // check on special bits - if (S_ISUID & ival) - strcat(buf, ",suid"); - if (S_ISGID & ival) - strcat(buf, ",sgid"); - if (S_ISVTX & ival) - strcat(buf, ",sticky"); - - // and the read, write, execute flags in octal - if (asprintf(&out, "%s,%03o", buf, - (S_IRWXU|S_IRWXG|S_IRWXO) & ival) < 0) - out = NULL; - return out; -} - -static const char *print_mode_short_int(unsigned int ival) -{ - char *out, buf[48]; - - // check on special bits - buf[0] = 0; - if (S_ISUID & ival) - strcat(buf, "suid"); - if (S_ISGID & ival) { - if (buf[0]) - strcat(buf, ","); - strcat(buf, "sgid"); - } - if (S_ISVTX & ival) { - if (buf[0]) - strcat(buf, ","); - strcat(buf, "sticky"); - } - - // and the read, write, execute flags in octal - if (buf[0] == 0) { - if (asprintf(&out, "0%03o", - (S_IRWXU|S_IRWXG|S_IRWXO) & ival) < 0) - out = NULL; - } else - if (asprintf(&out, "%s,0%03o", buf, - (S_IRWXU|S_IRWXG|S_IRWXO) & ival) < 0) - out = NULL; - return out; -} - -static const char *print_mode_short(const char *val, int base) -{ - unsigned int ival; - char *out; - - errno = 0; - ival = strtoul(val, NULL, base); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - return print_mode_short_int(ival); -} - -static const char *print_socket_domain(const char *val) -{ - int i; - char *out; - const char *str; - - errno = 0; - i = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - str = fam_i2s(i); - if (str == NULL) { - if (asprintf(&out, "unknown family(0x%s)", val) < 0) - out = NULL; - return out; - } else - return strdup(str); -} - -static const char *print_socket_type(const char *val) -{ - unsigned int type; - char *out; - const char *str; - - errno = 0; - type = 0xFF & strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - str = sock_type_i2s(type); - if (str == NULL) { - if (asprintf(&out, "unknown type(%s)", val) < 0) - out = NULL; - return out; - } else - return strdup(str); -} - -static const char *print_socket_proto(const char *val) -{ - unsigned int proto; - char *out; - struct protoent *p; - - errno = 0; - proto = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - p = getprotobynumber(proto); - if (p == NULL) { - if (asprintf(&out, "unknown proto(%s)", val) < 0) - out = NULL; - return out; - } else - return strdup(p->p_name); -} - -static const char *print_sockaddr(const char *val) -{ - int slen, rc = 0; - const struct sockaddr *saddr; - char name[NI_MAXHOST], serv[NI_MAXSERV]; - const char *host; - char *out = NULL; - const char *str; - - slen = strlen(val)/2; - host = au_unescape((char *)val); - if (host == NULL) { - if (asprintf(&out, "malformed host(%s)", val) < 0) - out = NULL; - return out; - } - saddr = (struct sockaddr *)host; - - - str = fam_i2s(saddr->sa_family); - if (str == NULL) { - if (asprintf(&out, "unknown family(%d)", saddr->sa_family) < 0) - out = NULL; - free((char *)host); - return out; - } - - // Now print address for some families - switch (saddr->sa_family) { - case AF_LOCAL: - { - const struct sockaddr_un *un = - (struct sockaddr_un *)saddr; - if (un->sun_path[0]) - rc = asprintf(&out, "%s %s", str, - un->sun_path); - else // abstract name - rc = asprintf(&out, "%s %.108s", str, - &un->sun_path[1]); - } - break; - case AF_INET: - if (slen < sizeof(struct sockaddr_in)) { - rc = asprintf(&out, "%s sockaddr len too short", - str); - break; - } - slen = sizeof(struct sockaddr_in); - if (getnameinfo(saddr, slen, name, NI_MAXHOST, serv, - NI_MAXSERV, NI_NUMERICHOST | - NI_NUMERICSERV) == 0 ) { - rc = asprintf(&out, "%s host:%s serv:%s", str, - name, serv); - } else - rc = asprintf(&out, "%s (error resolving addr)", - str); - break; - case AF_AX25: - { - const struct sockaddr_ax25 *x = - (struct sockaddr_ax25 *)saddr; - rc = asprintf(&out, "%s call:%c%c%c%c%c%c%c", - str, - x->sax25_call.ax25_call[0], - x->sax25_call.ax25_call[1], - x->sax25_call.ax25_call[2], - x->sax25_call.ax25_call[3], - x->sax25_call.ax25_call[4], - x->sax25_call.ax25_call[5], - x->sax25_call.ax25_call[6]); - } - break; - case AF_IPX: - { - const struct sockaddr_ipx *ip = - (struct sockaddr_ipx *)saddr; - rc = asprintf(&out, "%s port:%d net:%u", str, - ip->sipx_port, ip->sipx_network); - } - break; - case AF_ATMPVC: - { - const struct sockaddr_atmpvc* at = - (struct sockaddr_atmpvc *)saddr; - rc = asprintf(&out, "%s int:%d", str, - at->sap_addr.itf); - } - break; - case AF_X25: - { - const struct sockaddr_x25* x = - (struct sockaddr_x25 *)saddr; - rc = asprintf(&out, "%s addr:%.15s", str, - x->sx25_addr.x25_addr); - } - break; - case AF_INET6: - if (slen < sizeof(struct sockaddr_in6)) { - rc = asprintf(&out, - "%s sockaddr6 len too short", - str); - break; - } - slen = sizeof(struct sockaddr_in6); - if (getnameinfo(saddr, slen, name, NI_MAXHOST, serv, - NI_MAXSERV, NI_NUMERICHOST | - NI_NUMERICSERV) == 0 ) { - rc = asprintf(&out, "%s host:%s serv:%s", str, - name, serv); - } else - rc = asprintf(&out, "%s (error resolving addr)", - str); - break; - case AF_NETLINK: - { - const struct sockaddr_nl *n = - (struct sockaddr_nl *)saddr; - rc = asprintf(&out, "%s pid:%u", str, - n->nl_pid); - } - break; - } - if (rc < 0) - out = NULL; - free((char *)host); - return out; -} - -/* This is only used in the RHEL4 kernel */ -static const char *print_flags(const char *val) -{ - int flags, cnt = 0; - size_t i; - char *out, buf[80]; - - errno = 0; - flags = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - if (flags == 0) { - if (asprintf(&out, "none") < 0) - out = NULL; - return out; - } - buf[0] = 0; - for (i=0; i<FLAG_NUM_ENTRIES; i++) { - if (flag_table[i].value & flags) { - if (!cnt) { - strcat(buf, - flag_strings + flag_table[i].offset); - cnt++; - } else { - strcat(buf, ","); - strcat(buf, - flag_strings + flag_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static const char *print_promiscuous(const char *val) -{ - int ival; - - errno = 0; - ival = strtol(val, NULL, 10); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - if (ival == 0) - return strdup("no"); - else - return strdup("yes"); -} - -static const char *print_capabilities(const char *val, int base) -{ - int cap; - char *out; - const char *s; - - errno = 0; - cap = strtoul(val, NULL, base); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = cap_i2s(cap); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown capability(%s%s)", - base == 16 ? "0x" : "", val) < 0) - out = NULL; - return out; -} - -static const char *print_cap_bitmap(const char *val) -{ -#define MASK(x) (1U << (x)) - unsigned long long temp; - __u32 caps[2]; - int i, found=0; - char *p, buf[600]; // 17 per cap * 33 - - errno = 0; - temp = strtoull(val, NULL, 16); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - caps[0] = temp & 0x00000000FFFFFFFFLL; - caps[1] = (temp & 0xFFFFFFFF00000000LL) >> 32; - p = buf; - for (i=0; i <= CAP_LAST_CAP; i++) { - if (MASK(i%32) & caps[i/32]) { - const char *s; - if (found) - p = stpcpy(p, ","); - s = cap_i2s(i); - if (s != NULL) - p = stpcpy(p, s); - found = 1; - } - } - if (found == 0) - return strdup("none"); - return strdup(buf); -} - -static const char *print_success(const char *val) -{ - int res; - - if (isdigit(*val)) { - errno = 0; - res = strtoul(val, NULL, 10); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - return strdup(aulookup_success(res)); - } else - return strdup(val); -} - -static const char *print_open_flags(const char *val) -{ - size_t i; - unsigned int flags; - int cnt = 0; - char *out, buf[178]; - - errno = 0; - flags = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - buf[0] = 0; - if ((flags & O_ACCMODE) == 0) { - // Handle O_RDONLY specially - strcat(buf, "O_RDONLY"); - cnt++; - } - for (i=0; i<OPEN_FLAG_NUM_ENTRIES; i++) { - if (open_flag_table[i].value & flags) { - if (!cnt) { - strcat(buf, - open_flag_strings + open_flag_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - open_flag_strings + open_flag_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static const char *print_clone_flags(const char *val) -{ - unsigned int flags, i, clone_sig; - int cnt = 0; - char *out, buf[362]; // added 10 for signal name - - errno = 0; - flags = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - buf[0] = 0; - for (i=0; i<CLONE_FLAG_NUM_ENTRIES; i++) { - if (clone_flag_table[i].value & flags) { - if (!cnt) { - strcat(buf, - clone_flag_strings + clone_flag_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - clone_flag_strings + clone_flag_table[i].offset); - } - } - } - clone_sig = flags & 0xFF; - if (clone_sig && (clone_sig < 32)) { - const char *s = signal_i2s(clone_sig); - if (s != NULL) { - if (buf[0] != 0) - strcat(buf, "|"); - strcat(buf, s); - } - } - - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%x", flags); - return strdup(buf); -} - -static const char *print_fcntl_cmd(const char *val) -{ - char *out; - const char *s; - int cmd; - - errno = 0; - cmd = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = fcntl_i2s(cmd); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown fcntl command(%d)", cmd) < 0) - out = NULL; - return out; -} - -static const char *print_epoll_ctl(const char *val) -{ - char *out; - const char *s; - int cmd; - - errno = 0; - cmd = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = epoll_ctl_i2s(cmd); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown epoll_ctl operation (%d)", cmd) < 0) - out = NULL; - return out; -} - -static const char *print_clock_id(const char *val) -{ - int i; - char *out; - - errno = 0; - i = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - else if (i < 7) { - const char *s = clock_i2s(i); - if (s != NULL) - return strdup(s); - } - if (asprintf(&out, "unknown clk_id (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_prot(const char *val, unsigned int is_mmap) -{ - unsigned int prot, i; - int cnt = 0, limit; - char buf[144]; - char *out; - - errno = 0; - prot = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - buf[0] = 0; - if ((prot & 0x07) == 0) { - // Handle PROT_NONE specially - strcat(buf, "PROT_NONE"); - return strdup(buf); - } - if (is_mmap) - limit = 4; - else - limit = 3; - for (i=0; i<limit; i++) { - if (prot_table[i].value & prot) { - if (!cnt) { - strcat(buf, - prot_strings + prot_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - prot_strings + prot_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static const char *print_mmap(const char *val) -{ - unsigned int maps, i; - int cnt = 0; - char buf[176]; - char *out; - - errno = 0; - maps = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - buf[0] = 0; - if ((maps & 0x0F) == 0) { - // Handle MAP_FILE specially - strcat(buf, "MAP_FILE"); - cnt++; - } - for (i=0; i<MMAP_NUM_ENTRIES; i++) { - if (mmap_table[i].value & maps) { - if (!cnt) { - strcat(buf, - mmap_strings + mmap_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - mmap_strings + mmap_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static const char *print_personality(const char *val) -{ - int pers, pers2; - char *out; - const char *s; - - errno = 0; - pers = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - pers2 = pers & ~ADDR_NO_RANDOMIZE; - s = person_i2s(pers2); - if (s != NULL) { - if (pers & ADDR_NO_RANDOMIZE) { - if (asprintf(&out, "%s|~ADDR_NO_RANDOMIZE", s) < 0) - out = NULL; - return out; - } else - return strdup(s); - } - if (asprintf(&out, "unknown personality (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_ptrace(const char *val) -{ - int trace; - char *out; - const char *s; - - errno = 0; - trace = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = ptrace_i2s(trace); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown ptrace (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_prctl_opt(const char *val) -{ - int opt; - char *out; - const char *s; - - errno = 0; - opt = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = prctl_opt_i2s(opt); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown prctl option (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_mount(const char *val) -{ - unsigned int mounts, i; - int cnt = 0; - char buf[334]; - char *out; - - errno = 0; - mounts = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - buf[0] = 0; - for (i=0; i<MOUNT_NUM_ENTRIES; i++) { - if (mount_table[i].value & mounts) { - if (!cnt) { - strcat(buf, - mount_strings + mount_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - mount_strings + mount_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static const char *print_rlimit(const char *val) -{ - int i; - char *out; - - errno = 0; - i = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - else if (i < 17) { - const char *s = rlimit_i2s(i); - if (s != NULL) - return strdup(s); - } - if (asprintf(&out, "unknown rlimit (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_recv(const char *val) -{ - unsigned int rec, i; - int cnt = 0; - char buf[234]; - char *out; - - errno = 0; - rec = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - buf[0] = 0; - for (i=0; i<RECV_NUM_ENTRIES; i++) { - if (recv_table[i].value & rec) { - if (!cnt) { - strcat(buf, - recv_strings + recv_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - recv_strings + recv_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static const char *print_access(const char *val) -{ - unsigned long mode; - char buf[16]; - unsigned int i, cnt = 0; - - errno = 0; - mode = strtoul(val, NULL, 16); - if (errno) { - char *out; - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - if ((mode & 0xF) == 0) - return strdup("F_OK"); - buf[0] = 0; - for (i=0; i<3; i++) { - if (access_table[i].value & mode) { - if (!cnt) { - strcat(buf, - access_strings + access_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - access_strings + access_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static char *print_dirfd(const char *val) -{ - char *out; - - if (strcmp(val, "-100") == 0) { - if (asprintf(&out, "AT_FDCWD") < 0) - out = NULL; - } else { - if (asprintf(&out, "0x%s", val) < 0) - out = NULL; - } - return out; -} - -#ifndef SCHED_RESET_ON_FORK -#define SCHED_RESET_ON_FORK 0x40000000 -#endif -static const char *print_sched(const char *val) -{ - unsigned int pol; - char *out; - const char *s; - - errno = 0; - pol = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = sched_i2s(pol & 0x0F); - if (s != NULL) { - char buf[48]; - - strcpy(buf, s); - if (pol & SCHED_RESET_ON_FORK ) - strcat(buf, "|SCHED_RESET_ON_FORK"); - return strdup(buf); - } - if (asprintf(&out, "unknown scheduler policy (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_sock_opt_level(const char *val) -{ - int lvl; - char *out; - - errno = 0; - lvl = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - if (lvl == SOL_SOCKET) - return strdup("SOL_SOCKET"); - else { - struct protoent *p = getprotobynumber(lvl); - if (p == NULL) { - const char *s = socklevel_i2s(lvl); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown sockopt level (0x%s)", val) < 0) - out = NULL; - } else - return strdup(p->p_name); - } - - return out; -} - -static const char *print_sock_opt_name(const char *val, int machine) -{ - int opt; - char *out; - const char *s; - - errno = 0; - opt = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - // PPC's tables are different - if ((machine == MACH_PPC64 || machine == MACH_PPC) && - opt >= 16 && opt <= 21) - opt+=100; - - s = sockoptname_i2s(opt); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown sockopt name (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_ip_opt_name(const char *val) -{ - int opt; - char *out; - const char *s; - - errno = 0; - opt = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = ipoptname_i2s(opt); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown ipopt name (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_ip6_opt_name(const char *val) -{ - int opt; - char *out; - const char *s; - - errno = 0; - opt = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = ip6optname_i2s(opt); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown ip6opt name (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_tcp_opt_name(const char *val) -{ - int opt; - char *out; - const char *s; - - errno = 0; - opt = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = tcpoptname_i2s(opt); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown tcpopt name (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_udp_opt_name(const char *val) -{ - int opt; - char *out; - - errno = 0; - opt = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - if (opt == 1) - out = strdup("UDP_CORK"); - else if (opt == 100) - out = strdup("UDP_ENCAP"); - else if (asprintf(&out, "unknown udpopt name (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_pkt_opt_name(const char *val) -{ - int opt; - char *out; - const char *s; - - errno = 0; - opt = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = pktoptname_i2s(opt); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown pktopt name (0x%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_shmflags(const char *val) -{ - unsigned int flags, partial, i; - int cnt = 0; - char *out, buf[32]; - - errno = 0; - flags = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - partial = flags & 00003000; - buf[0] = 0; - for (i=0; i<IPCCMD_NUM_ENTRIES; i++) { - if (ipccmd_table[i].value & partial) { - if (!cnt) { - strcat(buf, - ipccmd_strings + ipccmd_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - ipccmd_strings + ipccmd_table[i].offset); - } - } - } - - partial = flags & 00014000; - for (i=0; i<SHM_MODE_NUM_ENTRIES; i++) { - if (shm_mode_table[i].value & partial) { - if (!cnt) { - strcat(buf, - shm_mode_strings + shm_mode_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - shm_mode_strings + shm_mode_table[i].offset); - } - } - } - - partial = flags & 000777; - const char *tmode = print_mode_short_int(partial); - if (tmode) { - if (buf[0] != 0) - strcat(buf, "|"); - strcat(buf, tmode); - free((void *)tmode); - } - - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%x", flags); - return strdup(buf); -} - -static const char *print_seek(const char *val) -{ - unsigned int whence; - char *out; - const char *str; - - errno = 0; - whence = 0xFF & strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - str = seek_i2s(whence); - if (str == NULL) { - if (asprintf(&out, "unknown whence(%s)", val) < 0) - out = NULL; - return out; - } else - return strdup(str); -} - -static const char *print_umount(const char *val) -{ - unsigned int flags, i; - int cnt = 0; - char buf[64]; - char *out; - - errno = 0; - flags = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - buf[0] = 0; - for (i=0; i<UMOUNT_NUM_ENTRIES; i++) { - if (umount_table[i].value & flags) { - if (!cnt) { - strcat(buf, - umount_strings + umount_table[i].offset); - cnt++; - } else { - strcat(buf, "|"); - strcat(buf, - umount_strings + umount_table[i].offset); - } - } - } - if (buf[0] == 0) - snprintf(buf, sizeof(buf), "0x%s", val); - return strdup(buf); -} - -static const char *print_ioctl_req(const char *val) -{ - int req; - char *out; - const char *r; - - errno = 0; - req = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - r = ioctlreq_i2s(req); - if (r != NULL) - return strdup(r); - if (asprintf(&out, "0x%s", val) < 0) - out = NULL; - return out; -} - -static const char *print_a0(const char *val, const idata *id) -{ - char *out; - int machine = id->machine, syscall = id->syscall; - const char *sys = audit_syscall_to_name(syscall, machine); - if (sys) { - if (*sys == 'r') { - if (strcmp(sys, "rt_sigaction") == 0) - return print_signals(val, 16); - else if (strcmp(sys, "renameat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "readlinkat") == 0) - return print_dirfd(val); - } else if (*sys == 'c') { - if (strcmp(sys, "clone") == 0) - return print_clone_flags(val); - else if (strcmp(sys, "clock_settime") == 0) - return print_clock_id(val); - } else if (*sys == 'p') { - if (strcmp(sys, "personality") == 0) - return print_personality(val); - else if (strcmp(sys, "ptrace") == 0) - return print_ptrace(val); - else if (strcmp(sys, "prctl") == 0) - return print_prctl_opt(val); - } else if (*sys == 'm') { - if (strcmp(sys, "mkdirat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "mknodat") == 0) - return print_dirfd(val); - } else if (*sys == 'f') { - if (strcmp(sys, "fchownat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "futimesat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "fchmodat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "faccessat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "futimensat") == 0) - return print_dirfd(val); - } else if (*sys == 'u') { - if (strcmp(sys, "unshare") == 0) - return print_clone_flags(val); - else if (strcmp(sys, "unlinkat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "utimensat") == 0) - return print_dirfd(val); - } else if (strcmp(sys+1, "etrlimit") == 0) - return print_rlimit(val); - else if (*sys == 's') { - if (strcmp(sys, "setuid") == 0) - return print_uid(val, 16); - else if (strcmp(sys, "setreuid") == 0) - return print_uid(val, 16); - else if (strcmp(sys, "setresuid") == 0) - return print_uid(val, 16); - else if (strcmp(sys, "setfsuid") == 0) - return print_uid(val, 16); - else if (strcmp(sys, "setgid") == 0) - return print_gid(val, 16); - else if (strcmp(sys, "setregid") == 0) - return print_gid(val, 16); - else if (strcmp(sys, "setresgid") == 0) - return print_gid(val, 16); - else if (strcmp(sys, "socket") == 0) - return print_socket_domain(val); - else if (strcmp(sys, "setfsgid") == 0) - return print_gid(val, 16); - else if (strcmp(sys, "socketcall") == 0) - return print_socketcall(val, 16); - } - else if (strcmp(sys, "linkat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "newfstatat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "openat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "ipccall") == 0) - return print_ipccall(val, 16); - } - if (asprintf(&out, "0x%s", val) < 0) - out = NULL; - return out; -} - -static const char *print_a1(const char *val, const idata *id) -{ - char *out; - int machine = id->machine, syscall = id->syscall; - const char *sys = audit_syscall_to_name(syscall, machine); - if (sys) { - if (*sys == 'f') { - if (strcmp(sys, "fchmod") == 0) - return print_mode_short(val, 16); - else if (strncmp(sys, "fcntl", 5) == 0) - return print_fcntl_cmd(val); - } else if (*sys == 'c') { - if (strcmp(sys, "chmod") == 0) - return print_mode_short(val, 16); - else if (strstr(sys, "chown")) - return print_uid(val, 16); - else if (strcmp(sys, "creat") == 0) - return print_mode_short(val, 16); - } - if (strcmp(sys+1, "etsockopt") == 0) - return print_sock_opt_level(val); - else if (*sys == 's') { - if (strcmp(sys, "setreuid") == 0) - return print_uid(val, 16); - else if (strcmp(sys, "setresuid") == 0) - return print_uid(val, 16); - else if (strcmp(sys, "setregid") == 0) - return print_gid(val, 16); - else if (strcmp(sys, "setresgid") == 0) - return print_gid(val, 16); - else if (strcmp(sys, "socket") == 0) - return print_socket_type(val); - else if (strcmp(sys, "setns") == 0) - return print_clone_flags(val); - else if (strcmp(sys, "sched_setscheduler") == 0) - return print_sched(val); - } else if (*sys == 'm') { - if (strcmp(sys, "mkdir") == 0) - return print_mode_short(val, 16); - else if (strcmp(sys, "mknod") == 0) - return print_mode(val, 16); - else if (strcmp(sys, "mq_open") == 0) - return print_open_flags(val); - } - else if (strcmp(sys, "open") == 0) - return print_open_flags(val); - else if (strcmp(sys, "access") == 0) - return print_access(val); - else if (strcmp(sys, "epoll_ctl") == 0) - return print_epoll_ctl(val); - else if (strcmp(sys, "kill") == 0) - return print_signals(val, 16); - else if (strcmp(sys, "prctl") == 0) { - if (id->a0 == PR_CAPBSET_READ || - id->a0 == PR_CAPBSET_DROP) - return print_capabilities(val, 16); - else if (id->a0 == PR_SET_PDEATHSIG) - return print_signals(val, 16); - } - else if (strcmp(sys, "tkill") == 0) - return print_signals(val, 16); - else if (strcmp(sys, "umount2") == 0) - return print_umount(val); - else if (strcmp(sys, "ioctl") == 0) - return print_ioctl_req(val); - } - if (asprintf(&out, "0x%s", val) < 0) - out = NULL; - return out; -} - -static const char *print_a2(const char *val, const idata *id) -{ - char *out; - int machine = id->machine, syscall = id->syscall; - const char *sys = audit_syscall_to_name(syscall, machine); - if (sys) { - if (strncmp(sys, "fcntl", 5) == 0) { - int ival; - - errno = 0; - ival = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", - val) < 0) - out = NULL; - return out; - } - switch (id->a1) - { - case F_SETOWN: - return print_uid(val, 16); - case F_SETFD: - if (ival == FD_CLOEXEC) - return strdup("FD_CLOEXEC"); - /* Fall thru okay. */ - case F_SETFL: - case F_SETLEASE: - case F_GETLEASE: - case F_NOTIFY: - break; - } - } else if (strcmp(sys+1, "etsockopt") == 0) { - if (id->a1 == IPPROTO_IP) - return print_ip_opt_name(val); - else if (id->a1 == SOL_SOCKET) - return print_sock_opt_name(val, machine); - else if (id->a1 == IPPROTO_TCP) - return print_tcp_opt_name(val); - else if (id->a1 == IPPROTO_UDP) - return print_udp_opt_name(val); - else if (id->a1 == IPPROTO_IPV6) - return print_ip6_opt_name(val); - else if (id->a1 == SOL_PACKET) - return print_pkt_opt_name(val); - else - goto normal; - } else if (*sys == 'o') { - if (strcmp(sys, "openat") == 0) - return print_open_flags(val); - if ((strcmp(sys, "open") == 0) && (id->a1 & O_CREAT)) - return print_mode_short(val, 16); - } else if (*sys == 'f') { - if (strcmp(sys, "fchmodat") == 0) - return print_mode_short(val, 16); - else if (strcmp(sys, "faccessat") == 0) - return print_access(val); - } else if (*sys == 's') { - if (strcmp(sys, "setresuid") == 0) - return print_uid(val, 16); - else if (strcmp(sys, "setresgid") == 0) - return print_gid(val, 16); - else if (strcmp(sys, "socket") == 0) - return print_socket_proto(val); - else if (strcmp(sys, "sendmsg") == 0) - return print_recv(val); - else if (strcmp(sys, "shmget") == 0) - return print_shmflags(val); - } else if (*sys == 'm') { - if (strcmp(sys, "mmap") == 0) - return print_prot(val, 1); - else if (strcmp(sys, "mkdirat") == 0) - return print_mode_short(val, 16); - else if (strcmp(sys, "mknodat") == 0) - return print_mode_short(val, 16); - else if (strcmp(sys, "mprotect") == 0) - return print_prot(val, 0); - else if ((strcmp(sys, "mq_open") == 0) && - (id->a1 & O_CREAT)) - return print_mode_short(val, 16); - } else if (*sys == 'r') { - if (strcmp(sys, "recvmsg") == 0) - return print_recv(val); - else if (strcmp(sys, "readlinkat") == 0) - return print_dirfd(val); - } else if (*sys == 'l') { - if (strcmp(sys, "linkat") == 0) - return print_dirfd(val); - else if (strcmp(sys, "lseek") == 0) - return print_seek(val); - } - else if (strstr(sys, "chown")) - return print_gid(val, 16); - else if (strcmp(sys, "tgkill") == 0) - return print_signals(val, 16); - } -normal: - if (asprintf(&out, "0x%s", val) < 0) - out = NULL; - return out; -} - -static const char *print_a3(const char *val, const idata *id) -{ - char *out; - int machine = id->machine, syscall = id->syscall; - const char *sys = audit_syscall_to_name(syscall, machine); - if (sys) { - if (*sys == 'm') { - if (strcmp(sys, "mmap") == 0) - return print_mmap(val); - else if (strcmp(sys, "mount") == 0) - return print_mount(val); - } else if (*sys == 'r') { - if (strcmp(sys, "recv") == 0) - return print_recv(val); - else if (strcmp(sys, "recvfrom") == 0) - return print_recv(val); - else if (strcmp(sys, "recvmmsg") == 0) - return print_recv(val); - } else if (*sys == 's') { - if (strcmp(sys, "send") == 0) - return print_recv(val); - else if (strcmp(sys, "sendto") == 0) - return print_recv(val); - else if (strcmp(sys, "sendmmsg") == 0) - return print_recv(val); - } - } - if (asprintf(&out, "0x%s", val) < 0) - out = NULL; - return out; -} - -static const char *print_signals(const char *val, unsigned int base) -{ - int i; - char *out; - - errno = 0; - i = strtoul(val, NULL, base); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - else if (i < 32) { - const char *s = signal_i2s(i); - if (s != NULL) - return strdup(s); - } - if (asprintf(&out, "unknown signal (%s%s)", - base == 16 ? "0x" : "", val) < 0) - out = NULL; - return out; -} - -static const char *print_nfproto(const char *val) -{ - int proto; - char *out; - const char *s; - - errno = 0; - proto = strtoul(val, NULL, 10); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = nfproto_i2s(proto); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown netfilter protocol (%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_icmptype(const char *val) -{ - int icmptype; - char *out; - const char *s; - - errno = 0; - icmptype = strtoul(val, NULL, 10); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - - s = icmptype_i2s(icmptype); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown icmp type (%s)", val) < 0) - out = NULL; - return out; -} - -static const char *print_protocol(const char *val) -{ - int i; - char *out; - - errno = 0; - i = strtoul(val, NULL, 10); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - } else { - struct protoent *p = getprotobynumber(i); - if (p) - out = strdup(p->p_name); - else - out = strdup("undefined protocol"); - } - return out; -} - -static const char *print_addr(const char *val) -{ - char *out = strdup(val); - return out; -} - -static const char *print_list(const char *val) -{ - int i; - char *out; - - errno = 0; - i = strtoul(val, NULL, 10); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - } else - out = strdup(audit_flag_to_name(i)); - return out; -} - -struct string_buf { - char *buf; /* NULL if was ever out of memory */ - size_t allocated; - size_t pos; -}; - -/* Append c to buf. */ -static void append_char(struct string_buf *buf, char c) -{ - if (buf->buf == NULL) - return; - if (buf->pos == buf->allocated) { - char *p; - - buf->allocated *= 2; - p = realloc(buf->buf, buf->allocated); - if (p == NULL) { - free(buf->buf); - buf->buf = NULL; - return; - } - buf->buf = p; - } - buf->buf[buf->pos] = c; - buf->pos++; -} - -/* Represent c as a character within a quoted string, and append it to buf. */ -static void tty_append_printable_char(struct string_buf *buf, unsigned char c) -{ - if (c < 0x20 || c > 0x7E) { - append_char(buf, '\\'); - append_char(buf, '0' + ((c >> 6) & 07)); - append_char(buf, '0' + ((c >> 3) & 07)); - append_char(buf, '0' + (c & 07)); - } else { - if (c == '\\' || c == '"') - append_char(buf, '\\'); - append_char(buf, c); - } -} - -/* Search for a name of a sequence of TTY bytes. - If found, return the name and advance *INPUT. Return NULL otherwise. */ -static const char *tty_find_named_key(unsigned char **input, size_t input_len) -{ - /* NUL-terminated list of (sequence, NUL, name, NUL) entries. - First match wins, even if a longer match were possible later */ - static const unsigned char named_keys[] = -#define E(SEQ, NAME) SEQ "\0" NAME "\0" -#include "tty_named_keys.h" -#undef E - "\0"; - - unsigned char *src; - const unsigned char *nk; - - src = *input; - if (*src >= ' ' && (*src < 0x7F || *src >= 0xA0)) - return NULL; /* Fast path */ - nk = named_keys; - do { - const unsigned char *p; - size_t nk_len; - - p = strchr(nk, '\0'); - nk_len = p - nk; - if (nk_len <= input_len && memcmp(src, nk, nk_len) == 0) { - *input += nk_len; - return p + 1; - } - nk = strchr(p + 1, '\0') + 1; - } while (*nk != '\0'); - return NULL; -} - -static const char *print_tty_data(const char *raw_data) -{ - struct string_buf buf; - int in_printable; - unsigned char *data, *data_pos, *data_end; - - if (!is_hex_string(raw_data)) - return strdup(raw_data); - data = au_unescape((char *)raw_data); - if (data == NULL) - return NULL; - data_end = data + strlen(raw_data) / 2; - - buf.allocated = 10; - buf.buf = malloc(buf.allocated); /* NULL handled in append_char() */ - buf.pos = 0; - in_printable = 0; - data_pos = data; - while (data_pos < data_end) { - /* FIXME: Unicode */ - const char *desc; - - desc = tty_find_named_key(&data_pos, data_end - data_pos); - if (desc != NULL) { - if (in_printable != 0) { - append_char(&buf, '"'); - in_printable = 0; - } - if (buf.pos != 0) - append_char(&buf, ','); - append_char(&buf, '<'); - while (*desc != '\0') { - append_char(&buf, *desc); - desc++; - } - append_char(&buf, '>'); - } else { - if (in_printable == 0) { - if (buf.pos != 0) - append_char(&buf, ','); - append_char(&buf, '"'); - in_printable = 1; - } - tty_append_printable_char(&buf, *data_pos); - data_pos++; - } - } - if (in_printable != 0) - append_char(&buf, '"'); - append_char(&buf, '\0'); - free(data); - return buf.buf; -} - -static const char *print_session(const char *val) -{ - if (strcmp(val, "4294967295") == 0) - return strdup("unset"); - else - return strdup(val); -} - -#define SECCOMP_RET_ACTION 0x7fff0000U -static const char *print_seccomp_code(const char *val) -{ - unsigned long code; - char *out; - const char *s; - - errno = 0; - code = strtoul(val, NULL, 16); - if (errno) { - if (asprintf(&out, "conversion error(%s)", val) < 0) - out = NULL; - return out; - } - s = seccomp_i2s(code & SECCOMP_RET_ACTION); - if (s != NULL) - return strdup(s); - if (asprintf(&out, "unknown seccomp code (%s)", val) < 0) - out = NULL; - return out; -} - -int lookup_type(const char *name) -{ - int i; - - if (type_s2i(name, &i) != 0) - return i; - return AUPARSE_TYPE_UNCLASSIFIED; -} - -const char *interpret(const rnode *r) -{ - const nvlist *nv = &r->nv; - int type; - idata id; - nvnode *n; - const char *out; - - id.machine = r->machine; - id.syscall = r->syscall; - id.a0 = r->a0; - id.a1 = r->a1; - id.name = nvlist_get_cur_name(nv); - id.val = nvlist_get_cur_val(nv); - type = auparse_interp_adjust_type(r->type, id.name, id.val); - - out = auparse_do_interpretation(type, &id); - n = nvlist_get_cur(nv); - n->interp_val = (char *)out; - - return out; -} - -/* - * rtype: the record type - * name: the current field name - * value: the current field value - * Returns: field's internal type is returned - */ -int auparse_interp_adjust_type(int rtype, const char *name, const char *val) -{ - int type; - - /* This set of statements overrides or corrects the detection. - * In almost all cases its a double use of a field. */ - if (rtype == AUDIT_EXECVE && *name == 'a' && strcmp(name, "argc") && - !strstr(name, "_len")) - type = AUPARSE_TYPE_ESCAPED; - else if (rtype == AUDIT_AVC && strcmp(name, "saddr") == 0) - type = AUPARSE_TYPE_UNCLASSIFIED; - else if (rtype == AUDIT_USER_TTY && strcmp(name, "msg") == 0) - type = AUPARSE_TYPE_ESCAPED; - else if (rtype == AUDIT_NETFILTER_PKT && strcmp(name, "saddr") == 0) - type = AUPARSE_TYPE_ADDR; - else if (strcmp(name, "acct") == 0) { - if (val[0] == '"') - type = AUPARSE_TYPE_ESCAPED; - else if (is_hex_string(val)) - type = AUPARSE_TYPE_ESCAPED; - else - type = AUPARSE_TYPE_UNCLASSIFIED; - } else if (rtype == AUDIT_PATH && *name =='f' && - strcmp(name, "flags") == 0) - type = AUPARSE_TYPE_FLAGS; - else if (rtype == AUDIT_MQ_OPEN && strcmp(name, "mode") == 0) - type = AUPARSE_TYPE_MODE_SHORT; - else if (rtype == AUDIT_CRYPTO_KEY_USER && strcmp(name, "fp") == 0) - type = AUPARSE_TYPE_UNCLASSIFIED; - else if ((strcmp(name, "id") == 0) && - (rtype == AUDIT_ADD_GROUP || rtype == AUDIT_GRP_MGMT || - rtype == AUDIT_DEL_GROUP)) - type = AUPARSE_TYPE_GID; - else - type = lookup_type(name); - - return type; -} -hidden_def(auparse_interp_adjust_type) - -const char *auparse_do_interpretation(int type, const idata *id) -{ - const char *out; - switch(type) { - case AUPARSE_TYPE_UID: - out = print_uid(id->val, 10); - break; - case AUPARSE_TYPE_GID: - out = print_gid(id->val, 10); - break; - case AUPARSE_TYPE_SYSCALL: - out = print_syscall(id); - break; - case AUPARSE_TYPE_ARCH: - out = print_arch(id->val, id->machine); - break; - case AUPARSE_TYPE_EXIT: - out = print_exit(id->val); - break; - case AUPARSE_TYPE_ESCAPED: - out = print_escaped(id->val); - break; - case AUPARSE_TYPE_PERM: - out = print_perm(id->val); - break; - case AUPARSE_TYPE_MODE: - out = print_mode(id->val,8); - break; - case AUPARSE_TYPE_MODE_SHORT: - out = print_mode_short(id->val,8); - break; - case AUPARSE_TYPE_SOCKADDR: - out = print_sockaddr(id->val); - break; - case AUPARSE_TYPE_FLAGS: - out = print_flags(id->val); - break; - case AUPARSE_TYPE_PROMISC: - out = print_promiscuous(id->val); - break; - case AUPARSE_TYPE_CAPABILITY: - out = print_capabilities(id->val, 10); - break; - case AUPARSE_TYPE_SUCCESS: - out = print_success(id->val); - break; - case AUPARSE_TYPE_A0: - out = print_a0(id->val, id); - break; - case AUPARSE_TYPE_A1: - out = print_a1(id->val, id); - break; - case AUPARSE_TYPE_A2: - out = print_a2(id->val, id); - break; - case AUPARSE_TYPE_A3: - out = print_a3(id->val, id); - break; - case AUPARSE_TYPE_SIGNAL: - out = print_signals(id->val, 10); - break; - case AUPARSE_TYPE_LIST: - out = print_list(id->val); - break; - case AUPARSE_TYPE_TTY_DATA: - out = print_tty_data(id->val); - break; - case AUPARSE_TYPE_SESSION: - out = print_session(id->val); - break; - case AUPARSE_TYPE_CAP_BITMAP: - out = print_cap_bitmap(id->val); - break; - case AUPARSE_TYPE_NFPROTO: - out = print_nfproto(id->val); - break; - case AUPARSE_TYPE_ICMPTYPE: - out = print_icmptype(id->val); - break; - case AUPARSE_TYPE_PROTOCOL: - out = print_protocol(id->val); - break; - case AUPARSE_TYPE_ADDR: - out = print_addr(id->val); - break; - case AUPARSE_TYPE_PERSONALITY: - out = print_personality(id->val); - break; - case AUPARSE_TYPE_SECCOMP: - out = print_seccomp_code(id->val); - break; - case AUPARSE_TYPE_OFLAG: - out = print_open_flags(id->val); - break; - case AUPARSE_TYPE_MMAP: - out = print_mmap(id->val); - break; - case AUPARSE_TYPE_PROCTITLE: - out = print_proctitle(id->val); - break; - case AUPARSE_TYPE_MAC_LABEL: - case AUPARSE_TYPE_UNCLASSIFIED: - default: - out = strdup(id->val); - break; - } - - if (escape_mode != AUPARSE_ESC_RAW) { - unsigned int len = strlen(out); - unsigned int cnt = need_escaping(out, len); - if (cnt) { - char *dest = malloc(len + 1 + (3*cnt)); - if (dest) - escape(out, dest, len); - free((void *)out); - out = dest; - } - } - return out; -} -hidden_def(auparse_do_interpretation) - |