static int insert_rule(int audit_fd, const char *field) { int rc; int flags = AUDIT_FILTER_ENTRY; int action = AUDIT_ALWAYS; struct audit_rule_data *rule = malloc(sizeof(struct audit_rule_data)); if (rule == NULL) goto err; memset(rule, 0, sizeof(struct audit_rule_data)); if (threat) { rc = 0; rc |= audit_rule_syscallbyname_data(rule, "open"); rc |= audit_rule_syscallbyname_data(rule, "openat"); rc |= audit_rule_syscallbyname_data(rule, "creat"); rc |= audit_rule_syscallbyname_data(rule, "truncate"); rc |= audit_rule_syscallbyname_data(rule, "rename"); rc |= audit_rule_syscallbyname_data(rule, "renameat"); rc |= audit_rule_syscallbyname_data(rule, "unlink"); rc |= audit_rule_syscallbyname_data(rule, "unlinkat"); rc |= audit_rule_syscallbyname_data(rule, "mknod"); rc |= audit_rule_syscallbyname_data(rule, "mknodat"); rc |= audit_rule_syscallbyname_data(rule, "mkdir"); rc |= audit_rule_syscallbyname_data(rule, "mkdirat"); rc |= audit_rule_syscallbyname_data(rule, "rmdir"); rc |= audit_rule_syscallbyname_data(rule, "chdir"); rc |= audit_rule_syscallbyname_data(rule, "chown"); rc |= audit_rule_syscallbyname_data(rule, "lchown"); rc |= audit_rule_syscallbyname_data(rule, "fchownat"); rc |= audit_rule_syscallbyname_data(rule, "chmod"); rc |= audit_rule_syscallbyname_data(rule, "fchmodat"); rc |= audit_rule_syscallbyname_data(rule, "link"); rc |= audit_rule_syscallbyname_data(rule, "linkat"); rc |= audit_rule_syscallbyname_data(rule, "symlink"); rc |= audit_rule_syscallbyname_data(rule, "symlinkat"); rc |= audit_rule_syscallbyname_data(rule, "readlink"); rc |= audit_rule_syscallbyname_data(rule, "readlinkat"); rc |= audit_rule_syscallbyname_data(rule, "execve"); rc |= audit_rule_syscallbyname_data(rule, "connect"); rc |= audit_rule_syscallbyname_data(rule, "bind"); rc |= audit_rule_syscallbyname_data(rule, "accept"); rc |= audit_rule_syscallbyname_data(rule, "sendto"); rc |= audit_rule_syscallbyname_data(rule, "recvfrom"); rc |= audit_rule_syscallbyname_data(rule, "sendfile"); } else rc = audit_rule_syscallbyname_data(rule, "all"); if (rc < 0) goto err; rc = audit_rule_fieldpair_data(&rule, field, flags); if (rc < 0) goto err; rc = audit_add_rule_data(audit_fd, rule, flags, action); if (rc < 0) goto err; return 0; err: fprintf(stderr, "Error inserting audit rule for %s\n", field); return 1; }
/* * This function is called after setopt to handle the return code. * On entry, status = 0 means just get the reply. Greater than 0 means we * are adding or deleting a rule or watch. -1 means an error occurred. * -2 means everything is OK and no reply needed. Even if there's an * error, we need to call this routine to close up the audit fd. * The return code from this function is 0 success and -1 error. */ static int handle_request(int status) { if (status == 0) { if (_audit_syscalladded) { fprintf(stderr, "Error - no list specified\n"); return -1; } get_reply(); } else if (status == -2) status = 0; // report success else if (status > 0) { int rc; if (add != AUDIT_FILTER_UNSET) { // if !task add syscall any if not specified if ((add & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK && _audit_syscalladded != 1) { audit_rule_syscallbyname_data( rule_new, "all"); } set_aumessage_mode(MSG_QUIET, DBG_NO); rc = audit_add_rule_data(fd, rule_new, add, action); set_aumessage_mode(MSG_STDERR, DBG_NO); /* Retry for legacy kernels */ if (rc < 0) { if (errno == EINVAL && rule_new->fields[0] == AUDIT_DIR) { rule_new->fields[0] = AUDIT_WATCH; rc = audit_add_rule_data(fd, rule_new, add, action); } else { fprintf(stderr, "Error sending add rule data request (%s)\n", errno == EEXIST ? "Rule exists" : strerror(-rc)); } } } else if (del != AUDIT_FILTER_UNSET) { if ((del & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK && _audit_syscalladded != 1) { audit_rule_syscallbyname_data( rule_new, "all"); } set_aumessage_mode(MSG_QUIET, DBG_NO); rc = audit_delete_rule_data(fd, rule_new, del, action); set_aumessage_mode(MSG_STDERR, DBG_NO); /* Retry for legacy kernels */ if (rc < 0) { if (errno == EINVAL && rule_new->fields[0] == AUDIT_DIR) { rule_new->fields[0] = AUDIT_WATCH; rc = audit_delete_rule_data(fd,rule_new, del, action); } else { fprintf(stderr, "Error sending delete rule data request (%s)\n", errno == EEXIST ? "Rule exists" : strerror(-rc)); } } } else { usage(); audit_close(fd); exit(1); } if (rc <= 0) status = -1; else status = 0; } else status = -1; audit_close(fd); fd = -1; return status; }
static int insert_rule(int audit_fd, const char *field) { int rc; int flags = AUDIT_FILTER_EXIT; int action = AUDIT_ALWAYS; struct audit_rule_data *rule = malloc(sizeof(struct audit_rule_data)); int machine = audit_detect_machine(); char *t_field = NULL; if (rule == NULL) goto err; memset(rule, 0, sizeof(struct audit_rule_data)); if (threat) { rc = 0; rc |= audit_rule_syscallbyname_data(rule, "open"); rc |= audit_rule_syscallbyname_data(rule, "openat"); rc |= audit_rule_syscallbyname_data(rule, "creat"); rc |= audit_rule_syscallbyname_data(rule, "truncate"); rc |= audit_rule_syscallbyname_data(rule, "rename"); rc |= audit_rule_syscallbyname_data(rule, "renameat"); rc |= audit_rule_syscallbyname_data(rule, "unlink"); rc |= audit_rule_syscallbyname_data(rule, "unlinkat"); rc |= audit_rule_syscallbyname_data(rule, "mknod"); rc |= audit_rule_syscallbyname_data(rule, "mknodat"); rc |= audit_rule_syscallbyname_data(rule, "mkdir"); rc |= audit_rule_syscallbyname_data(rule, "mkdirat"); rc |= audit_rule_syscallbyname_data(rule, "rmdir"); rc |= audit_rule_syscallbyname_data(rule, "chdir"); rc |= audit_rule_syscallbyname_data(rule, "chown"); rc |= audit_rule_syscallbyname_data(rule, "lchown"); rc |= audit_rule_syscallbyname_data(rule, "fchownat"); rc |= audit_rule_syscallbyname_data(rule, "chmod"); rc |= audit_rule_syscallbyname_data(rule, "fchmodat"); rc |= audit_rule_syscallbyname_data(rule, "link"); rc |= audit_rule_syscallbyname_data(rule, "linkat"); rc |= audit_rule_syscallbyname_data(rule, "symlink"); rc |= audit_rule_syscallbyname_data(rule, "symlinkat"); rc |= audit_rule_syscallbyname_data(rule, "readlink"); rc |= audit_rule_syscallbyname_data(rule, "readlinkat"); rc |= audit_rule_syscallbyname_data(rule, "execve"); rc |= audit_rule_syscallbyname_data(rule, "name_to_handle_at"); if (machine != MACH_X86 && machine != MACH_S390X && machine != MACH_S390) { rc |= audit_rule_syscallbyname_data(rule, "connect"); rc |= audit_rule_syscallbyname_data(rule, "bind"); rc |= audit_rule_syscallbyname_data(rule, "accept"); rc |= audit_rule_syscallbyname_data(rule, "sendto"); rc |= audit_rule_syscallbyname_data(rule, "recvfrom"); rc |= audit_rule_syscallbyname_data(rule, "accept4"); } rc |= audit_rule_syscallbyname_data(rule, "sendfile"); } else rc = audit_rule_syscallbyname_data(rule, "all"); if (rc < 0) goto err; t_field = strdup(field); rc = audit_rule_fieldpair_data(&rule, t_field, flags); free(t_field); if (rc < 0) goto err; rc = audit_add_rule_data(audit_fd, rule, flags, action); if (rc < 0) goto err; // Now if i386, lets add its network rules if (machine == MACH_X86 || machine == MACH_S390X || machine == MACH_S390) { int i, a0[6] = { SYS_CONNECT, SYS_BIND, SYS_ACCEPT, SYS_SENDTO, SYS_RECVFROM, SYS_ACCEPT4 }; for (i=0; i<6; i++) { char pair[32]; memset(rule, 0, sizeof(struct audit_rule_data)); rc |= audit_rule_syscallbyname_data(rule, "socketcall"); snprintf(pair, sizeof(pair), "a0=%d", a0[i]); rc |= audit_rule_fieldpair_data(&rule, pair, flags); t_field = strdup(field); rc |= audit_rule_fieldpair_data(&rule, t_field, flags); free(t_field); rc |= audit_add_rule_data(audit_fd, rule, flags, action); } } free(rule); return 0; err: fprintf(stderr, "Error inserting audit rule for %s\n", field); free(rule); return 1; }