Index: head/sys/security/audit/audit_bsm.c =================================================================== --- head/sys/security/audit/audit_bsm.c (revision 336603) +++ head/sys/security/audit/audit_bsm.c (revision 336604) @@ -1,1766 +1,1769 @@ /* * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1999-2009 Apple Inc. * Copyright (c) 2016-2017 Robert N. M. Watson * All rights reserved. * * Portions of this software were developed by BAE Systems, the University of * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent * Computing (TC) research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include MALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data"); static void audit_sys_auditon(struct audit_record *ar, struct au_record *rec); /* * Initialize the BSM auditing subsystem. */ void kau_init(void) { au_evclassmap_init(); au_evnamemap_init(); } /* * This call reserves memory for the audit record. Memory must be guaranteed * before any auditable event can be generated. The au_record structure * maintains a reference to the memory allocated above and also the list of * tokens associated with this record. */ static struct au_record * kau_open(void) { struct au_record *rec; rec = malloc(sizeof(*rec), M_AUDITBSM, M_WAITOK); rec->data = NULL; TAILQ_INIT(&rec->token_q); rec->len = 0; rec->used = 1; return (rec); } /* * Store the token with the record descriptor. */ static void kau_write(struct au_record *rec, struct au_token *tok) { KASSERT(tok != NULL, ("kau_write: tok == NULL")); TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens); rec->len += tok->len; } /* * Close out the audit record by adding the header token, identifying any * missing tokens. Write out the tokens to the record memory. */ static void kau_close(struct au_record *rec, struct timespec *ctime, short event) { u_char *dptr; size_t tot_rec_size; token_t *cur, *hdr, *trail; struct timeval tm; size_t hdrsize; struct auditinfo_addr ak; struct in6_addr *ap; audit_get_kinfo(&ak); hdrsize = 0; switch (ak.ai_termid.at_type) { case AU_IPv4: hdrsize = (ak.ai_termid.at_addr[0] == INADDR_ANY) ? AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&ak); break; case AU_IPv6: ap = (struct in6_addr *)&ak.ai_termid.at_addr[0]; hdrsize = (IN6_IS_ADDR_UNSPECIFIED(ap)) ? AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&ak); break; default: panic("kau_close: invalid address family"); } tot_rec_size = rec->len + hdrsize + AUDIT_TRAILER_SIZE; rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO); tm.tv_usec = ctime->tv_nsec / 1000; tm.tv_sec = ctime->tv_sec; if (hdrsize != AUDIT_HEADER_SIZE) hdr = au_to_header32_ex_tm(tot_rec_size, event, 0, tm, &ak); else hdr = au_to_header32_tm(tot_rec_size, event, 0, tm); TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens); trail = au_to_trailer(tot_rec_size); TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens); rec->len = tot_rec_size; dptr = rec->data; TAILQ_FOREACH(cur, &rec->token_q, tokens) { memcpy(dptr, cur->t_data, cur->len); dptr += cur->len; } } /* * Free a BSM audit record by releasing all the tokens and clearing the audit * record information. */ void kau_free(struct au_record *rec) { struct au_token *tok; /* Free the token list. */ while ((tok = TAILQ_FIRST(&rec->token_q))) { TAILQ_REMOVE(&rec->token_q, tok, tokens); free(tok->t_data, M_AUDITBSM); free(tok, M_AUDITBSM); } rec->used = 0; rec->len = 0; free(rec->data, M_AUDITBSM); free(rec, M_AUDITBSM); } /* * XXX: May want turn some (or all) of these macros into functions in order * to reduce the generated code size. * * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the * caller are OK with this. */ #define ATFD1_TOKENS(argnum) do { \ if (ARG_IS_VALID(kar, ARG_ATFD1)) { \ tok = au_to_arg32(argnum, "at fd 1", ar->ar_arg_atfd1); \ kau_write(rec, tok); \ } \ } while (0) #define ATFD2_TOKENS(argnum) do { \ if (ARG_IS_VALID(kar, ARG_ATFD2)) { \ tok = au_to_arg32(argnum, "at fd 2", ar->ar_arg_atfd2); \ kau_write(rec, tok); \ } \ } while (0) #define UPATH1_TOKENS do { \ if (ARG_IS_VALID(kar, ARG_UPATH1)) { \ tok = au_to_path(ar->ar_arg_upath1); \ kau_write(rec, tok); \ } \ } while (0) #define UPATH2_TOKENS do { \ if (ARG_IS_VALID(kar, ARG_UPATH2)) { \ tok = au_to_path(ar->ar_arg_upath2); \ kau_write(rec, tok); \ } \ } while (0) #define VNODE1_TOKENS do { \ if (ARG_IS_VALID(kar, ARG_ATFD)) { \ tok = au_to_arg32(1, "at fd", ar->ar_arg_atfd); \ kau_write(rec, tok); \ } \ if (ARG_IS_VALID(kar, ARG_VNODE1)) { \ tok = au_to_attr32(&ar->ar_arg_vnode1); \ kau_write(rec, tok); \ } \ } while (0) #define UPATH1_VNODE1_TOKENS do { \ UPATH1_TOKENS; \ if (ARG_IS_VALID(kar, ARG_VNODE1)) { \ tok = au_to_attr32(&ar->ar_arg_vnode1); \ kau_write(rec, tok); \ } \ } while (0) #define VNODE2_TOKENS do { \ if (ARG_IS_VALID(kar, ARG_VNODE2)) { \ tok = au_to_attr32(&ar->ar_arg_vnode2); \ kau_write(rec, tok); \ } \ } while (0) #define FD_VNODE1_TOKENS do { \ if (ARG_IS_VALID(kar, ARG_VNODE1)) { \ if (ARG_IS_VALID(kar, ARG_FD)) { \ tok = au_to_arg32(1, "fd", ar->ar_arg_fd); \ kau_write(rec, tok); \ } \ tok = au_to_attr32(&ar->ar_arg_vnode1); \ kau_write(rec, tok); \ } else { \ if (ARG_IS_VALID(kar, ARG_FD)) { \ tok = au_to_arg32(1, "non-file: fd", \ ar->ar_arg_fd); \ kau_write(rec, tok); \ } \ } \ } while (0) #define PROCESS_PID_TOKENS(argn) do { \ if ((ar->ar_arg_pid > 0) /* Reference a single process */ \ && (ARG_IS_VALID(kar, ARG_PROCESS))) { \ tok = au_to_process32_ex(ar->ar_arg_auid, \ ar->ar_arg_euid, ar->ar_arg_egid, \ ar->ar_arg_ruid, ar->ar_arg_rgid, \ ar->ar_arg_pid, ar->ar_arg_asid, \ &ar->ar_arg_termid_addr); \ kau_write(rec, tok); \ } else if (ARG_IS_VALID(kar, ARG_PID)) { \ tok = au_to_arg32(argn, "process", ar->ar_arg_pid); \ kau_write(rec, tok); \ } \ } while (0) #define EXTATTR_TOKENS(namespace_argnum) do { \ if (ARG_IS_VALID(kar, ARG_VALUE)) { \ switch (ar->ar_arg_value) { \ case EXTATTR_NAMESPACE_USER: \ tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\ break; \ case EXTATTR_NAMESPACE_SYSTEM: \ tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\ break; \ default: \ tok = au_to_arg32((namespace_argnum), \ "attrnamespace", ar->ar_arg_value); \ break; \ } \ kau_write(rec, tok); \ } \ /* attrname is in the text field */ \ if (ARG_IS_VALID(kar, ARG_TEXT)) { \ tok = au_to_text(ar->ar_arg_text); \ kau_write(rec, tok); \ } \ } while (0) /* * Not all pointer arguments to system calls are of interest, but in some * cases they reflect delegation of rights, such as mmap(2) followed by * minherit(2) before execve(2), so do the best we can. */ #define ADDR_TOKEN(argnum, argname) do { \ if (ARG_IS_VALID(kar, ARG_ADDR)) { \ if (sizeof(void *) == sizeof(uint32_t)) \ tok = au_to_arg32((argnum), (argname), \ (uint32_t)(uintptr_t)ar->ar_arg_addr); \ else \ tok = au_to_arg64((argnum), (argname), \ (uint64_t)(uintptr_t)ar->ar_arg_addr); \ kau_write(rec, tok); \ } \ } while (0) /* * Implement auditing for the auditon() system call. The audit tokens that * are generated depend on the command that was sent into the auditon() * system call. */ static void audit_sys_auditon(struct audit_record *ar, struct au_record *rec) { struct au_token *tok; tok = au_to_arg32(3, "length", ar->ar_arg_len); kau_write(rec, tok); switch (ar->ar_arg_cmd) { case A_OLDSETPOLICY: if ((size_t)ar->ar_arg_len == sizeof(int64_t)) { tok = au_to_arg64(2, "policy", ar->ar_arg_auditon.au_policy64); kau_write(rec, tok); break; } /* FALLTHROUGH */ case A_SETPOLICY: tok = au_to_arg32(2, "policy", ar->ar_arg_auditon.au_policy); kau_write(rec, tok); break; case A_SETKMASK: tok = au_to_arg32(2, "setkmask:as_success", ar->ar_arg_auditon.au_mask.am_success); kau_write(rec, tok); tok = au_to_arg32(2, "setkmask:as_failure", ar->ar_arg_auditon.au_mask.am_failure); kau_write(rec, tok); break; case A_OLDSETQCTRL: if ((size_t)ar->ar_arg_len == sizeof(au_qctrl64_t)) { tok = au_to_arg64(2, "setqctrl:aq_hiwater", ar->ar_arg_auditon.au_qctrl64.aq64_hiwater); kau_write(rec, tok); tok = au_to_arg64(2, "setqctrl:aq_lowater", ar->ar_arg_auditon.au_qctrl64.aq64_lowater); kau_write(rec, tok); tok = au_to_arg64(2, "setqctrl:aq_bufsz", ar->ar_arg_auditon.au_qctrl64.aq64_bufsz); kau_write(rec, tok); tok = au_to_arg64(2, "setqctrl:aq_delay", ar->ar_arg_auditon.au_qctrl64.aq64_delay); kau_write(rec, tok); tok = au_to_arg64(2, "setqctrl:aq_minfree", ar->ar_arg_auditon.au_qctrl64.aq64_minfree); kau_write(rec, tok); break; } /* FALLTHROUGH */ case A_SETQCTRL: tok = au_to_arg32(2, "setqctrl:aq_hiwater", ar->ar_arg_auditon.au_qctrl.aq_hiwater); kau_write(rec, tok); tok = au_to_arg32(2, "setqctrl:aq_lowater", ar->ar_arg_auditon.au_qctrl.aq_lowater); kau_write(rec, tok); tok = au_to_arg32(2, "setqctrl:aq_bufsz", ar->ar_arg_auditon.au_qctrl.aq_bufsz); kau_write(rec, tok); tok = au_to_arg32(2, "setqctrl:aq_delay", ar->ar_arg_auditon.au_qctrl.aq_delay); kau_write(rec, tok); tok = au_to_arg32(2, "setqctrl:aq_minfree", ar->ar_arg_auditon.au_qctrl.aq_minfree); kau_write(rec, tok); break; case A_SETUMASK: tok = au_to_arg32(2, "setumask:as_success", ar->ar_arg_auditon.au_auinfo.ai_mask.am_success); kau_write(rec, tok); tok = au_to_arg32(2, "setumask:as_failure", ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure); kau_write(rec, tok); break; case A_SETSMASK: tok = au_to_arg32(2, "setsmask:as_success", ar->ar_arg_auditon.au_auinfo.ai_mask.am_success); kau_write(rec, tok); tok = au_to_arg32(2, "setsmask:as_failure", ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure); kau_write(rec, tok); break; case A_OLDSETCOND: if ((size_t)ar->ar_arg_len == sizeof(int64_t)) { tok = au_to_arg64(2, "setcond", ar->ar_arg_auditon.au_cond64); kau_write(rec, tok); break; } /* FALLTHROUGH */ case A_SETCOND: tok = au_to_arg32(2, "setcond", ar->ar_arg_auditon.au_cond); kau_write(rec, tok); break; case A_SETCLASS: tok = au_to_arg32(2, "setclass:ec_event", ar->ar_arg_auditon.au_evclass.ec_number); kau_write(rec, tok); tok = au_to_arg32(2, "setclass:ec_class", ar->ar_arg_auditon.au_evclass.ec_class); kau_write(rec, tok); break; case A_SETPMASK: tok = au_to_arg32(2, "setpmask:as_success", ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success); kau_write(rec, tok); tok = au_to_arg32(2, "setpmask:as_failure", ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure); kau_write(rec, tok); break; case A_SETFSIZE: tok = au_to_arg32(2, "setfsize:filesize", ar->ar_arg_auditon.au_fstat.af_filesz); kau_write(rec, tok); break; default: break; } } /* * Convert an internal kernel audit record to a BSM record and return a * success/failure indicator. The BSM record is passed as an out parameter to * this function. * * Return conditions: * BSM_SUCCESS: The BSM record is valid * BSM_FAILURE: Failure; the BSM record is NULL. * BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL. */ int kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) { struct au_token *tok, *subj_tok, *jail_tok; struct au_record *rec; au_tid_t tid; struct audit_record *ar; int ctr; KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL")); *pau = NULL; ar = &kar->k_ar; rec = kau_open(); /* * Create the subject token. If this credential was jailed be sure to * generate a zonename token. */ if (ar->ar_jailname[0] != '\0') jail_tok = au_to_zonename(ar->ar_jailname); else jail_tok = NULL; switch (ar->ar_subj_term_addr.at_type) { case AU_IPv4: tid.port = ar->ar_subj_term_addr.at_port; tid.machine = ar->ar_subj_term_addr.at_addr[0]; subj_tok = au_to_subject32(ar->ar_subj_auid, /* audit ID */ ar->ar_subj_cred.cr_uid, /* eff uid */ ar->ar_subj_egid, /* eff group id */ ar->ar_subj_ruid, /* real uid */ ar->ar_subj_rgid, /* real group id */ ar->ar_subj_pid, /* process id */ ar->ar_subj_asid, /* session ID */ &tid); break; case AU_IPv6: subj_tok = au_to_subject32_ex(ar->ar_subj_auid, ar->ar_subj_cred.cr_uid, ar->ar_subj_egid, ar->ar_subj_ruid, ar->ar_subj_rgid, ar->ar_subj_pid, ar->ar_subj_asid, &ar->ar_subj_term_addr); break; default: bzero(&tid, sizeof(tid)); subj_tok = au_to_subject32(ar->ar_subj_auid, ar->ar_subj_cred.cr_uid, ar->ar_subj_egid, ar->ar_subj_ruid, ar->ar_subj_rgid, ar->ar_subj_pid, ar->ar_subj_asid, &tid); } /* * The logic inside each case fills in the tokens required for the * event, except for the header, trailer, and return tokens. The * header and trailer tokens are added by the kau_close() function. * The return token is added outside of the switch statement. */ switch(ar->ar_event) { case AUE_ACCEPT: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SADDRINET)) { tok = au_to_sock_inet((struct sockaddr_in *) &ar->ar_arg_sockaddr); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) { tok = au_to_sock_unix((struct sockaddr_un *) &ar->ar_arg_sockaddr); kau_write(rec, tok); UPATH1_TOKENS; } break; case AUE_BIND: case AUE_LISTEN: case AUE_CONNECT: case AUE_RECV: case AUE_RECVFROM: case AUE_RECVMSG: case AUE_SEND: case AUE_SENDMSG: case AUE_SENDTO: /* * Socket-related events. */ if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SADDRINET)) { tok = au_to_sock_inet((struct sockaddr_in *) &ar->ar_arg_sockaddr); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) { tok = au_to_sock_unix((struct sockaddr_un *) &ar->ar_arg_sockaddr); kau_write(rec, tok); UPATH1_TOKENS; } /* XXX Need to handle ARG_SADDRINET6 */ break; case AUE_BINDAT: case AUE_CONNECTAT: ATFD1_TOKENS(1); if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(2, "fd", ar->ar_arg_fd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) { tok = au_to_sock_unix((struct sockaddr_un *) &ar->ar_arg_sockaddr); kau_write(rec, tok); UPATH1_TOKENS; } break; case AUE_SENDFILE: FD_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_SADDRINET)) { tok = au_to_sock_inet((struct sockaddr_in *) &ar->ar_arg_sockaddr); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) { tok = au_to_sock_unix((struct sockaddr_un *) &ar->ar_arg_sockaddr); kau_write(rec, tok); UPATH1_TOKENS; } /* XXX Need to handle ARG_SADDRINET6 */ break; case AUE_SOCKET: case AUE_SOCKETPAIR: if (ARG_IS_VALID(kar, ARG_SOCKINFO)) { tok = au_to_arg32(1, "domain", ar->ar_arg_sockinfo.so_domain); kau_write(rec, tok); tok = au_to_arg32(2, "type", ar->ar_arg_sockinfo.so_type); kau_write(rec, tok); tok = au_to_arg32(3, "protocol", ar->ar_arg_sockinfo.so_protocol); kau_write(rec, tok); } break; case AUE_SETSOCKOPT: case AUE_SHUTDOWN: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } break; case AUE_ACCT: if (ARG_IS_VALID(kar, ARG_UPATH1)) { UPATH1_VNODE1_TOKENS; } else { tok = au_to_arg32(1, "accounting off", 0); kau_write(rec, tok); } break; case AUE_SETAUID: if (ARG_IS_VALID(kar, ARG_AUID)) { tok = au_to_arg32(2, "setauid", ar->ar_arg_auid); kau_write(rec, tok); } break; case AUE_SETAUDIT: if (ARG_IS_VALID(kar, ARG_AUID) && ARG_IS_VALID(kar, ARG_ASID) && ARG_IS_VALID(kar, ARG_AMASK) && ARG_IS_VALID(kar, ARG_TERMID)) { tok = au_to_arg32(1, "setaudit:auid", ar->ar_arg_auid); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit:port", ar->ar_arg_termid.port); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit:machine", ar->ar_arg_termid.machine); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit:as_success", ar->ar_arg_amask.am_success); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit:as_failure", ar->ar_arg_amask.am_failure); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit:asid", ar->ar_arg_asid); kau_write(rec, tok); } break; case AUE_SETAUDIT_ADDR: if (ARG_IS_VALID(kar, ARG_AUID) && ARG_IS_VALID(kar, ARG_ASID) && ARG_IS_VALID(kar, ARG_AMASK) && ARG_IS_VALID(kar, ARG_TERMID_ADDR)) { tok = au_to_arg32(1, "setaudit_addr:auid", ar->ar_arg_auid); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit_addr:as_success", ar->ar_arg_amask.am_success); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit_addr:as_failure", ar->ar_arg_amask.am_failure); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit_addr:asid", ar->ar_arg_asid); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit_addr:type", ar->ar_arg_termid_addr.at_type); kau_write(rec, tok); tok = au_to_arg32(1, "setaudit_addr:port", ar->ar_arg_termid_addr.at_port); kau_write(rec, tok); if (ar->ar_arg_termid_addr.at_type == AU_IPv6) tok = au_to_in_addr_ex((struct in6_addr *) &ar->ar_arg_termid_addr.at_addr[0]); if (ar->ar_arg_termid_addr.at_type == AU_IPv4) tok = au_to_in_addr((struct in_addr *) &ar->ar_arg_termid_addr.at_addr[0]); kau_write(rec, tok); } break; case AUE_AUDITON: /* * For AUDITON commands without own event, audit the cmd. */ if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_AUDITON_GETCAR: case AUE_AUDITON_GETCLASS: case AUE_AUDITON_GETCOND: case AUE_AUDITON_GETCWD: case AUE_AUDITON_GETKMASK: case AUE_AUDITON_GETSTAT: case AUE_AUDITON_GPOLICY: case AUE_AUDITON_GQCTRL: case AUE_AUDITON_SETCLASS: case AUE_AUDITON_SETCOND: case AUE_AUDITON_SETKMASK: case AUE_AUDITON_SETSMASK: case AUE_AUDITON_SETSTAT: case AUE_AUDITON_SETUMASK: case AUE_AUDITON_SPOLICY: case AUE_AUDITON_SQCTRL: if (ARG_IS_VALID(kar, ARG_AUDITON)) audit_sys_auditon(ar, rec); break; case AUE_AUDITCTL: UPATH1_VNODE1_TOKENS; break; case AUE_EXIT: if (ARG_IS_VALID(kar, ARG_EXIT)) { tok = au_to_exit(ar->ar_arg_exitretval, ar->ar_arg_exitstatus); kau_write(rec, tok); } break; case AUE_ADJTIME: case AUE_CLOCK_SETTIME: case AUE_AUDIT: case AUE_DUP2: case AUE_GETAUDIT: case AUE_GETAUDIT_ADDR: case AUE_GETAUID: case AUE_GETCWD: case AUE_GETFSSTAT: case AUE_GETRESUID: case AUE_GETRESGID: case AUE_KQUEUE: case AUE_MODLOAD: case AUE_MODUNLOAD: case AUE_MSGSYS: case AUE_NTP_ADJTIME: case AUE_PIPE: case AUE_POSIX_OPENPT: case AUE_PROFILE: case AUE_RTPRIO: case AUE_SEMSYS: + case AUE_SETFIB: case AUE_SHMSYS: case AUE_SETPGRP: case AUE_SETRLIMIT: case AUE_SETSID: case AUE_SETTIMEOFDAY: case AUE_SYSARCH: /* * Header, subject, and return tokens added at end. */ break; case AUE_ACL_DELETE_FD: case AUE_ACL_DELETE_FILE: case AUE_ACL_CHECK_FD: case AUE_ACL_CHECK_FILE: case AUE_ACL_CHECK_LINK: case AUE_ACL_DELETE_LINK: case AUE_ACL_GET_FD: case AUE_ACL_GET_FILE: case AUE_ACL_GET_LINK: case AUE_ACL_SET_FD: case AUE_ACL_SET_FILE: case AUE_ACL_SET_LINK: if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(1, "type", ar->ar_arg_value); kau_write(rec, tok); } ATFD1_TOKENS(1); UPATH1_VNODE1_TOKENS; break; case AUE_CHDIR: case AUE_CHROOT: case AUE_FSTATAT: case AUE_FUTIMESAT: case AUE_GETATTRLIST: case AUE_JAIL: case AUE_LUTIMES: case AUE_NFS_GETFH: + case AUE_LGETFH: case AUE_LSTAT: case AUE_LPATHCONF: case AUE_PATHCONF: case AUE_READLINK: case AUE_READLINKAT: case AUE_REVOKE: case AUE_RMDIR: case AUE_SEARCHFS: case AUE_SETATTRLIST: case AUE_STAT: case AUE_STATFS: case AUE_SWAPON: case AUE_SWAPOFF: case AUE_TRUNCATE: case AUE_UNDELETE: case AUE_UNLINK: case AUE_UNLINKAT: case AUE_UTIMES: ATFD1_TOKENS(1); UPATH1_VNODE1_TOKENS; break; case AUE_ACCESS: case AUE_EACCESS: case AUE_FACCESSAT: ATFD1_TOKENS(1); UPATH1_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(2, "mode", ar->ar_arg_value); kau_write(rec, tok); } break; case AUE_FHSTATFS: case AUE_FHOPEN: case AUE_FHSTAT: /* XXXRW: Need to audit vnode argument. */ break; case AUE_CHFLAGS: case AUE_LCHFLAGS: + case AUE_CHFLAGSAT: if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_CHMOD: case AUE_LCHMOD: if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_FCHMODAT: ATFD1_TOKENS(1); if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(3, "new file mode", ar->ar_arg_mode); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_CHOWN: case AUE_LCHOWN: if (ARG_IS_VALID(kar, ARG_UID)) { tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_GID)) { tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_FCHOWNAT: ATFD1_TOKENS(1); if (ARG_IS_VALID(kar, ARG_UID)) { tok = au_to_arg32(3, "new file uid", ar->ar_arg_uid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_GID)) { tok = au_to_arg32(4, "new file gid", ar->ar_arg_gid); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_EXCHANGEDATA: UPATH1_VNODE1_TOKENS; UPATH2_TOKENS; break; case AUE_CLOSE: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_CLOSEFROM: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } break; case AUE_CORE: if (ARG_IS_VALID(kar, ARG_SIGNUM)) { tok = au_to_arg32(1, "signal", ar->ar_arg_signum); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_EXTATTRCTL: UPATH1_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd); kau_write(rec, tok); } /* extattrctl(2) filename parameter is in upath2/vnode2 */ UPATH2_TOKENS; VNODE2_TOKENS; EXTATTR_TOKENS(4); break; case AUE_EXTATTR_GET_FILE: case AUE_EXTATTR_SET_FILE: case AUE_EXTATTR_LIST_FILE: case AUE_EXTATTR_DELETE_FILE: case AUE_EXTATTR_GET_LINK: case AUE_EXTATTR_SET_LINK: case AUE_EXTATTR_LIST_LINK: case AUE_EXTATTR_DELETE_LINK: UPATH1_VNODE1_TOKENS; EXTATTR_TOKENS(2); break; case AUE_EXTATTR_GET_FD: case AUE_EXTATTR_SET_FD: case AUE_EXTATTR_LIST_FD: case AUE_EXTATTR_DELETE_FD: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(2, "fd", ar->ar_arg_fd); kau_write(rec, tok); } EXTATTR_TOKENS(2); break; case AUE_FEXECVE: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_EXECVE: case AUE_MAC_EXECVE: if (ARG_IS_VALID(kar, ARG_ARGV)) { tok = au_to_exec_args(ar->ar_arg_argv, ar->ar_arg_argc); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_ENVV)) { tok = au_to_exec_env(ar->ar_arg_envv, ar->ar_arg_envc); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_FCHMOD: if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode); kau_write(rec, tok); } FD_VNODE1_TOKENS; break; /* * XXXRW: Some of these need to handle non-vnode cases as well. */ case AUE_FCHDIR: case AUE_FPATHCONF: case AUE_FSTAT: case AUE_FSTATFS: case AUE_FSYNC: case AUE_FTRUNCATE: case AUE_FUTIMES: case AUE_GETDIRENTRIES: case AUE_GETDIRENTRIESATTR: case AUE_LSEEK: case AUE_POLL: case AUE_POSIX_FALLOCATE: case AUE_PREAD: case AUE_PWRITE: case AUE_READ: case AUE_READV: case AUE_WRITE: case AUE_WRITEV: FD_VNODE1_TOKENS; break; case AUE_FCHOWN: if (ARG_IS_VALID(kar, ARG_UID)) { tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_GID)) { tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid); kau_write(rec, tok); } FD_VNODE1_TOKENS; break; case AUE_FCNTL: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(2, "cmd", au_fcntl_cmd_to_bsm(ar->ar_arg_cmd)); kau_write(rec, tok); } FD_VNODE1_TOKENS; break; case AUE_FCHFLAGS: if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } FD_VNODE1_TOKENS; break; case AUE_FLOCK: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(2, "operation", ar->ar_arg_cmd); kau_write(rec, tok); } FD_VNODE1_TOKENS; break; case AUE_RFORK: if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(1, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_FORK: case AUE_VFORK: if (ARG_IS_VALID(kar, ARG_PID)) { tok = au_to_arg32(0, "child PID", ar->ar_arg_pid); kau_write(rec, tok); } break; case AUE_IOCTL: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_VNODE1)) FD_VNODE1_TOKENS; else { if (ARG_IS_VALID(kar, ARG_SOCKINFO)) { tok = kau_to_socket(&ar->ar_arg_sockinfo); kau_write(rec, tok); } else { if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } } } break; case AUE_KILL: case AUE_KILLPG: if (ARG_IS_VALID(kar, ARG_SIGNUM)) { tok = au_to_arg32(2, "signal", ar->ar_arg_signum); kau_write(rec, tok); } PROCESS_PID_TOKENS(1); break; case AUE_KTRACE: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(2, "ops", ar->ar_arg_cmd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(3, "trpoints", ar->ar_arg_value); kau_write(rec, tok); } PROCESS_PID_TOKENS(4); UPATH1_VNODE1_TOKENS; break; case AUE_LINK: case AUE_LINKAT: case AUE_RENAME: case AUE_RENAMEAT: ATFD1_TOKENS(1); UPATH1_VNODE1_TOKENS; ATFD2_TOKENS(3); UPATH2_TOKENS; break; case AUE_LOADSHFILE: ADDR_TOKEN(4, "base addr"); UPATH1_VNODE1_TOKENS; break; case AUE_MKDIR: case AUE_MKDIRAT: case AUE_MKFIFO: case AUE_MKFIFOAT: ATFD1_TOKENS(1); if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(2, "mode", ar->ar_arg_mode); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_MKNOD: case AUE_MKNODAT: ATFD1_TOKENS(1); if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(2, "mode", ar->ar_arg_mode); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_DEV)) { tok = au_to_arg32(3, "dev", ar->ar_arg_dev); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_MMAP: case AUE_MUNMAP: case AUE_MPROTECT: case AUE_MLOCK: case AUE_MUNLOCK: case AUE_MINHERIT: ADDR_TOKEN(1, "addr"); if (ARG_IS_VALID(kar, ARG_LEN)) { tok = au_to_arg32(2, "len", ar->ar_arg_len); kau_write(rec, tok); } if (ar->ar_event == AUE_MMAP) FD_VNODE1_TOKENS; if (ar->ar_event == AUE_MPROTECT) { if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(3, "protection", ar->ar_arg_value); kau_write(rec, tok); } } if (ar->ar_event == AUE_MINHERIT) { if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(3, "inherit", ar->ar_arg_value); kau_write(rec, tok); } } break; case AUE_MOUNT: case AUE_NMOUNT: /* XXX Need to handle NFS mounts */ if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(3, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_TEXT)) { tok = au_to_text(ar->ar_arg_text); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_NFS_SVC: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(1, "flags", ar->ar_arg_cmd); kau_write(rec, tok); } break; case AUE_UMOUNT: if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(2, "flags", ar->ar_arg_value); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_TEXT)) { tok = au_to_text(ar->ar_arg_text); kau_write(rec, tok); } break; case AUE_MSGCTL: ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd); /* Fall through */ case AUE_MSGRCV: case AUE_MSGSND: tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id); kau_write(rec, tok); if (ar->ar_errno != EINVAL) { tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id); kau_write(rec, tok); } break; case AUE_MSGGET: if (ar->ar_errno == 0) { if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) { tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id); kau_write(rec, tok); } } break; case AUE_RESETSHFILE: ADDR_TOKEN(1, "base addr"); break; case AUE_OPEN_RC: case AUE_OPEN_RTC: case AUE_OPEN_RWC: case AUE_OPEN_RWTC: case AUE_OPEN_WC: case AUE_OPEN_WTC: case AUE_CREAT: if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(3, "mode", ar->ar_arg_mode); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_OPEN_R: case AUE_OPEN_RT: case AUE_OPEN_RW: case AUE_OPEN_RWT: case AUE_OPEN_W: case AUE_OPEN_WT: if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_OPENAT_RC: case AUE_OPENAT_RTC: case AUE_OPENAT_RWC: case AUE_OPENAT_RWTC: case AUE_OPENAT_WC: case AUE_OPENAT_WTC: if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(3, "mode", ar->ar_arg_mode); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_OPENAT_R: case AUE_OPENAT_RT: case AUE_OPENAT_RW: case AUE_OPENAT_RWT: case AUE_OPENAT_W: case AUE_OPENAT_WT: if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } ATFD1_TOKENS(1); UPATH1_VNODE1_TOKENS; break; case AUE_PROCCTL: if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(1, "idtype", ar->ar_arg_value); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(2, "com", ar->ar_arg_cmd); kau_write(rec, tok); } PROCESS_PID_TOKENS(3); break; case AUE_PTRACE: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(1, "request", ar->ar_arg_cmd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(4, "data", ar->ar_arg_value); kau_write(rec, tok); } PROCESS_PID_TOKENS(2); break; case AUE_QUOTACTL: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(2, "command", ar->ar_arg_cmd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_UID)) { tok = au_to_arg32(3, "uid", ar->ar_arg_uid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_GID)) { tok = au_to_arg32(3, "gid", ar->ar_arg_gid); kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; break; case AUE_REBOOT: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(1, "howto", ar->ar_arg_cmd); kau_write(rec, tok); } break; case AUE_SEMCTL: ar->ar_event = audit_semctl_to_event(ar->ar_arg_svipc_cmd); /* Fall through */ case AUE_SEMOP: if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) { tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id); kau_write(rec, tok); if (ar->ar_errno != EINVAL) { tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id); kau_write(rec, tok); } } break; case AUE_SEMGET: if (ar->ar_errno == 0) { if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) { tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id); kau_write(rec, tok); } } break; case AUE_SETEGID: if (ARG_IS_VALID(kar, ARG_EGID)) { tok = au_to_arg32(1, "egid", ar->ar_arg_egid); kau_write(rec, tok); } break; case AUE_SETEUID: if (ARG_IS_VALID(kar, ARG_EUID)) { tok = au_to_arg32(1, "euid", ar->ar_arg_euid); kau_write(rec, tok); } break; case AUE_SETREGID: if (ARG_IS_VALID(kar, ARG_RGID)) { tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_EGID)) { tok = au_to_arg32(2, "egid", ar->ar_arg_egid); kau_write(rec, tok); } break; case AUE_SETREUID: if (ARG_IS_VALID(kar, ARG_RUID)) { tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_EUID)) { tok = au_to_arg32(2, "euid", ar->ar_arg_euid); kau_write(rec, tok); } break; case AUE_SETRESGID: if (ARG_IS_VALID(kar, ARG_RGID)) { tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_EGID)) { tok = au_to_arg32(2, "egid", ar->ar_arg_egid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SGID)) { tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid); kau_write(rec, tok); } break; case AUE_SETRESUID: if (ARG_IS_VALID(kar, ARG_RUID)) { tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_EUID)) { tok = au_to_arg32(2, "euid", ar->ar_arg_euid); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SUID)) { tok = au_to_arg32(3, "suid", ar->ar_arg_suid); kau_write(rec, tok); } break; case AUE_SETGID: if (ARG_IS_VALID(kar, ARG_GID)) { tok = au_to_arg32(1, "gid", ar->ar_arg_gid); kau_write(rec, tok); } break; case AUE_SETUID: if (ARG_IS_VALID(kar, ARG_UID)) { tok = au_to_arg32(1, "uid", ar->ar_arg_uid); kau_write(rec, tok); } break; case AUE_SETGROUPS: if (ARG_IS_VALID(kar, ARG_GROUPSET)) { for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++) { tok = au_to_arg32(1, "setgroups", ar->ar_arg_groups.gidset[ctr]); kau_write(rec, tok); } } break; case AUE_SETLOGIN: if (ARG_IS_VALID(kar, ARG_LOGIN)) { tok = au_to_text(ar->ar_arg_login); kau_write(rec, tok); } break; case AUE_SETPRIORITY: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(1, "which", ar->ar_arg_cmd); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_UID)) { tok = au_to_arg32(2, "who", ar->ar_arg_uid); kau_write(rec, tok); } PROCESS_PID_TOKENS(2); if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(3, "priority", ar->ar_arg_value); kau_write(rec, tok); } break; case AUE_SETPRIVEXEC: if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(1, "flag", ar->ar_arg_value); kau_write(rec, tok); } break; /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */ case AUE_SHMAT: if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) { tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id); kau_write(rec, tok); /* XXXAUDIT: Does having the ipc token make sense? */ tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) { tok = au_to_arg32(2, "shmaddr", (int)(uintptr_t)ar->ar_arg_svipc_addr); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) { tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm); kau_write(rec, tok); } break; case AUE_SHMCTL: if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) { tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id); kau_write(rec, tok); /* XXXAUDIT: Does having the ipc token make sense? */ tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id); kau_write(rec, tok); } switch (ar->ar_arg_svipc_cmd) { case IPC_STAT: ar->ar_event = AUE_SHMCTL_STAT; break; case IPC_RMID: ar->ar_event = AUE_SHMCTL_RMID; break; case IPC_SET: ar->ar_event = AUE_SHMCTL_SET; if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) { tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm); kau_write(rec, tok); } break; default: break; /* We will audit a bad command */ } break; case AUE_SHMDT: if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) { tok = au_to_arg32(1, "shmaddr", (int)(uintptr_t)ar->ar_arg_svipc_addr); kau_write(rec, tok); } break; case AUE_SHMGET: /* This is unusual; the return value is in an argument token */ if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) { tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id); kau_write(rec, tok); tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) { tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm); kau_write(rec, tok); } break; /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE * and AUE_SEMUNLINK are Posix IPC */ case AUE_SHMOPEN: if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(3, "mode", ar->ar_arg_mode); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_SHMUNLINK: UPATH1_TOKENS; if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) { struct ipc_perm perm; perm.uid = ar->ar_arg_pipc_perm.pipc_uid; perm.gid = ar->ar_arg_pipc_perm.pipc_gid; perm.cuid = ar->ar_arg_pipc_perm.pipc_uid; perm.cgid = ar->ar_arg_pipc_perm.pipc_gid; perm.mode = ar->ar_arg_pipc_perm.pipc_mode; perm.seq = 0; perm.key = 0; tok = au_to_ipc_perm(&perm); kau_write(rec, tok); } break; case AUE_SEMOPEN: if (ARG_IS_VALID(kar, ARG_FFLAGS)) { tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_MODE)) { tok = au_to_arg32(3, "mode", ar->ar_arg_mode); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(4, "value", ar->ar_arg_value); kau_write(rec, tok); } /* FALLTHROUGH */ case AUE_SEMUNLINK: if (ARG_IS_VALID(kar, ARG_TEXT)) { tok = au_to_text(ar->ar_arg_text); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) { struct ipc_perm perm; perm.uid = ar->ar_arg_pipc_perm.pipc_uid; perm.gid = ar->ar_arg_pipc_perm.pipc_gid; perm.cuid = ar->ar_arg_pipc_perm.pipc_uid; perm.cgid = ar->ar_arg_pipc_perm.pipc_gid; perm.mode = ar->ar_arg_pipc_perm.pipc_mode; perm.seq = 0; perm.key = 0; tok = au_to_ipc_perm(&perm); kau_write(rec, tok); } break; case AUE_SEMCLOSE: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "sem", ar->ar_arg_fd); kau_write(rec, tok); } break; case AUE_SYMLINK: case AUE_SYMLINKAT: if (ARG_IS_VALID(kar, ARG_TEXT)) { tok = au_to_text(ar->ar_arg_text); kau_write(rec, tok); } ATFD1_TOKENS(1); UPATH1_VNODE1_TOKENS; break; case AUE_SYSCTL: case AUE_SYSCTL_NONADMIN: if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) { for (ctr = 0; ctr < ar->ar_arg_len; ctr++) { tok = au_to_arg32(1, "name", ar->ar_arg_ctlname[ctr]); kau_write(rec, tok); } } if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(5, "newval", ar->ar_arg_value); kau_write(rec, tok); } if (ARG_IS_VALID(kar, ARG_TEXT)) { tok = au_to_text(ar->ar_arg_text); kau_write(rec, tok); } break; case AUE_UMASK: if (ARG_IS_VALID(kar, ARG_MASK)) { tok = au_to_arg32(1, "new mask", ar->ar_arg_mask); kau_write(rec, tok); } tok = au_to_arg32(0, "prev mask", ar->ar_retval); kau_write(rec, tok); break; case AUE_WAIT4: case AUE_WAIT6: PROCESS_PID_TOKENS(1); if (ARG_IS_VALID(kar, ARG_VALUE)) { tok = au_to_arg32(3, "options", ar->ar_arg_value); kau_write(rec, tok); } break; case AUE_CAP_RIGHTS_LIMIT: /* * XXXRW/XXXJA: Would be nice to audit socket/etc information. */ FD_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_RIGHTS)) { tok = au_to_rights(&ar->ar_arg_rights); kau_write(rec, tok); } break; case AUE_CAP_FCNTLS_GET: case AUE_CAP_IOCTLS_GET: case AUE_CAP_IOCTLS_LIMIT: case AUE_CAP_RIGHTS_GET: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "fd", ar->ar_arg_fd); kau_write(rec, tok); } break; case AUE_CAP_FCNTLS_LIMIT: FD_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_FCNTL_RIGHTS)) { tok = au_to_arg32(2, "fcntlrights", ar->ar_arg_fcntl_rights); kau_write(rec, tok); } break; case AUE_CAP_ENTER: case AUE_CAP_GETMODE: break; case AUE_NULL: default: printf("BSM conversion requested for unknown event %d\n", ar->ar_event); /* * Write the subject token so it is properly freed here. */ if (jail_tok != NULL) kau_write(rec, jail_tok); kau_write(rec, subj_tok); kau_free(rec); return (BSM_NOAUDIT); } if (jail_tok != NULL) kau_write(rec, jail_tok); kau_write(rec, subj_tok); tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval); kau_write(rec, tok); /* Every record gets a return token */ kau_close(rec, &ar->ar_endtime, ar->ar_event); *pau = rec; return (BSM_SUCCESS); } /* * Verify that a record is a valid BSM record. This verification is simple * now, but may be expanded on sometime in the future. Return 1 if the * record is good, 0 otherwise. */ int bsm_rec_verify(void *rec) { char c = *(char *)rec; /* * Check the token ID of the first token; it has to be a header * token. * * XXXAUDIT There needs to be a token structure to map a token. * XXXAUDIT 'Shouldn't be simply looking at the first char. */ if ((c != AUT_HEADER32) && (c != AUT_HEADER32_EX) && (c != AUT_HEADER64) && (c != AUT_HEADER64_EX)) return (0); return (1); } Index: head/tests/sys/audit/file-attribute-access.c =================================================================== --- head/tests/sys/audit/file-attribute-access.c (revision 336603) +++ head/tests/sys/audit/file-attribute-access.c (revision 336604) @@ -1,1247 +1,1241 @@ /*- * Copyright (c) 2018 Aniket Pandey * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include "utils.h" static struct pollfd fds[1]; static mode_t mode = 0777; static pid_t pid; static fhandle_t fht; static int filedesc, fhdesc; static char extregex[80]; static char buff[] = "ezio"; static struct stat statbuff; static struct statfs statfsbuff; static const char *auclass = "fa"; static const char *name = "authorname"; static const char *path = "fileforaudit"; static const char *errpath = "dirdoesnotexist/fileforaudit"; static const char *successreg = "fileforaudit.*return,success"; static const char *failurereg = "fileforaudit.*return,failure"; ATF_TC_WITH_CLEANUP(stat_success); ATF_TC_HEAD(stat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "stat(2) call"); } ATF_TC_BODY(stat_success, tc) { /* File needs to exist to call stat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, stat(path, &statbuff)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(stat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(stat_failure); ATF_TC_HEAD(stat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "stat(2) call"); } ATF_TC_BODY(stat_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, stat(errpath, &statbuff)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(stat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lstat_success); ATF_TC_HEAD(lstat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "lstat(2) call"); } ATF_TC_BODY(lstat_success, tc) { /* Symbolic link needs to exist to call lstat(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, lstat(path, &statbuff)); check_audit(fds, successreg, pipefd); } ATF_TC_CLEANUP(lstat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lstat_failure); ATF_TC_HEAD(lstat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "lstat(2) call"); } ATF_TC_BODY(lstat_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, lstat(errpath, &statbuff)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(lstat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fstat_success); ATF_TC_HEAD(fstat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fstat(2) call"); } ATF_TC_BODY(fstat_success, tc) { /* File needs to exist to call fstat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fstat(filedesc, &statbuff)); snprintf(extregex, sizeof(extregex), "fstat.*%jd.*return,success", (intmax_t)statbuff.st_ino); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fstat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fstat_failure); ATF_TC_HEAD(fstat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fstat(2) call"); } ATF_TC_BODY(fstat_failure, tc) { FILE *pipefd = setup(fds, auclass); const char *regex = "fstat.*return,failure : Bad file descriptor"; /* Failure reason: bad file descriptor */ ATF_REQUIRE_EQ(-1, fstat(-1, &statbuff)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fstat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fstatat_success); ATF_TC_HEAD(fstatat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fstatat(2) call"); } ATF_TC_BODY(fstatat_success, tc) { /* File or Symbolic link needs to exist to call lstat(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fstatat(AT_FDCWD, path, &statbuff, AT_SYMLINK_NOFOLLOW)); check_audit(fds, successreg, pipefd); } ATF_TC_CLEANUP(fstatat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fstatat_failure); ATF_TC_HEAD(fstatat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fstatat(2) call"); } ATF_TC_BODY(fstatat_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, fstatat(AT_FDCWD, path, &statbuff, AT_SYMLINK_NOFOLLOW)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(fstatat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(statfs_success); ATF_TC_HEAD(statfs_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "statfs(2) call"); } ATF_TC_BODY(statfs_success, tc) { /* File needs to exist to call statfs(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, statfs(path, &statfsbuff)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(statfs_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(statfs_failure); ATF_TC_HEAD(statfs_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "statfs(2) call"); } ATF_TC_BODY(statfs_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, statfs(errpath, &statfsbuff)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(statfs_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fstatfs_success); ATF_TC_HEAD(fstatfs_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fstatfs(2) call"); } ATF_TC_BODY(fstatfs_success, tc) { /* File needs to exist to call fstat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1); /* Call stat(2) to store the Inode number of 'path' */ ATF_REQUIRE_EQ(0, stat(path, &statbuff)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fstatfs(filedesc, &statfsbuff)); snprintf(extregex, sizeof(extregex), "fstatfs.*%jd.*return,success", (intmax_t)statbuff.st_ino); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fstatfs_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fstatfs_failure); ATF_TC_HEAD(fstatfs_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fstatfs(2) call"); } ATF_TC_BODY(fstatfs_failure, tc) { FILE *pipefd = setup(fds, auclass); const char *regex = "fstatfs.*return,failure : Bad file descriptor"; /* Failure reason: bad file descriptor */ ATF_REQUIRE_EQ(-1, fstatfs(-1, &statfsbuff)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fstatfs_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(getfsstat_success); ATF_TC_HEAD(getfsstat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "getfsstat(2) call"); } ATF_TC_BODY(getfsstat_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "getfsstat.*%d.*success", pid); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE(getfsstat(NULL, 0, MNT_NOWAIT) != -1); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(getfsstat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(getfsstat_failure); ATF_TC_HEAD(getfsstat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "getfsstat(2) call"); } ATF_TC_BODY(getfsstat_failure, tc) { const char *regex = "getfsstat.*return,failure : Invalid argument"; FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid value for mode */ ATF_REQUIRE_EQ(-1, getfsstat(NULL, 0, -1)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(getfsstat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lgetfh_success); ATF_TC_HEAD(lgetfh_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "lgetfh(2) call"); } ATF_TC_BODY(lgetfh_success, tc) { - /* BSM conversion requested for unknown event 43061 */ - atf_tc_expect_fail("PR 228374: lgetfh(2) does not get audited in success mode"); - /* Symbolic link needs to exist to get a file-handle */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); const char *regex = "lgetfh.*return,success"; FILE *pipefd = setup(fds, "fa"); ATF_REQUIRE_EQ(0, lgetfh(path, &fht)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(lgetfh_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lgetfh_failure); ATF_TC_HEAD(lgetfh_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "lgetfh(2) call"); } ATF_TC_BODY(lgetfh_failure, tc) { - /* BSM conversion requested for unknown event 43061 */ - atf_tc_expect_fail("PR 228374: lgetfh(2) does not get audited in failure mode"); - const char *regex = "lgetfh.*return,failure"; FILE *pipefd = setup(fds, "fa"); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, lgetfh(errpath, &fht)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(lgetfh_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fhopen_success); ATF_TC_HEAD(fhopen_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fhopen(2) call"); } ATF_TC_BODY(fhopen_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fhopen.*%d.*return,success", pid); /* File needs to exist to get a file-handle */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); /* Get the file handle to be passed to fhopen(2) */ ATF_REQUIRE_EQ(0, getfh(path, &fht)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((fhdesc = fhopen(&fht, O_RDWR)) != -1); check_audit(fds, extregex, pipefd); close(fhdesc); close(filedesc); } ATF_TC_CLEANUP(fhopen_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fhopen_failure); ATF_TC_HEAD(fhopen_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fhopen(2) call"); } ATF_TC_BODY(fhopen_failure, tc) { const char *regex = "fhopen.*return,failure : Invalid argument"; FILE *pipefd = setup(fds, auclass); /* * Failure reason: NULL does not represent any file handle * and O_CREAT is not allowed as the flag for fhopen(2) */ ATF_REQUIRE_EQ(-1, fhopen(NULL, O_CREAT)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fhopen_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fhstat_success); ATF_TC_HEAD(fhstat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fstat(2) call"); } ATF_TC_BODY(fhstat_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fhstat.*%d.*return,success", pid); /* File needs to exist to get a file-handle */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); /* Get the file handle to be passed to fhstat(2) */ ATF_REQUIRE_EQ(0, getfh(path, &fht)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fhstat(&fht, &statbuff)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fhstat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fhstat_failure); ATF_TC_HEAD(fhstat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fhstat(2) call"); } ATF_TC_BODY(fhstat_failure, tc) { const char *regex = "fhstat.*return,failure : Bad address"; FILE *pipefd = setup(fds, auclass); /* Failure reason: NULL does not represent any file handle */ ATF_REQUIRE_EQ(-1, fhstat(NULL, NULL)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fhstat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fhstatfs_success); ATF_TC_HEAD(fhstatfs_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fstatfs(2) call"); } ATF_TC_BODY(fhstatfs_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fhstatfs.*%d.*success", pid); /* File needs to exist to get a file-handle */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); /* Get the file handle to be passed to fhstatfs(2) */ ATF_REQUIRE_EQ(0, getfh(path, &fht)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fhstatfs(&fht, &statfsbuff)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fhstatfs_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fhstatfs_failure); ATF_TC_HEAD(fhstatfs_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fhstatfs(2) call"); } ATF_TC_BODY(fhstatfs_failure, tc) { const char *regex = "fhstatfs.*return,failure : Bad address"; FILE *pipefd = setup(fds, auclass); /* Failure reason: NULL does not represent any file handle */ ATF_REQUIRE_EQ(-1, fhstatfs(NULL, NULL)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fhstatfs_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(access_success); ATF_TC_HEAD(access_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "access(2) call"); } ATF_TC_BODY(access_success, tc) { /* File needs to exist to call access(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, access(path, F_OK)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(access_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(access_failure); ATF_TC_HEAD(access_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "access(2) call"); } ATF_TC_BODY(access_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, access(errpath, F_OK)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(access_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(eaccess_success); ATF_TC_HEAD(eaccess_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "eaccess(2) call"); } ATF_TC_BODY(eaccess_success, tc) { /* File needs to exist to call eaccess(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, eaccess(path, F_OK)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(eaccess_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(eaccess_failure); ATF_TC_HEAD(eaccess_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "eaccess(2) call"); } ATF_TC_BODY(eaccess_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, eaccess(errpath, F_OK)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(eaccess_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(faccessat_success); ATF_TC_HEAD(faccessat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "faccessat(2) call"); } ATF_TC_BODY(faccessat_success, tc) { /* File needs to exist to call faccessat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, faccessat(AT_FDCWD, path, F_OK, AT_EACCESS)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(faccessat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(faccessat_failure); ATF_TC_HEAD(faccessat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "faccessat(2) call"); } ATF_TC_BODY(faccessat_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, faccessat(AT_FDCWD, errpath, F_OK, AT_EACCESS)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(faccessat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(pathconf_success); ATF_TC_HEAD(pathconf_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "pathconf(2) call"); } ATF_TC_BODY(pathconf_success, tc) { /* File needs to exist to call pathconf(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); /* Get the maximum number of bytes of filename */ ATF_REQUIRE(pathconf(path, _PC_NAME_MAX) != -1); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(pathconf_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(pathconf_failure); ATF_TC_HEAD(pathconf_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "pathconf(2) call"); } ATF_TC_BODY(pathconf_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, pathconf(errpath, _PC_NAME_MAX)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(pathconf_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lpathconf_success); ATF_TC_HEAD(lpathconf_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "lpathconf(2) call"); } ATF_TC_BODY(lpathconf_success, tc) { /* Symbolic link needs to exist to call lpathconf(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); /* Get the maximum number of bytes of symlink's name */ ATF_REQUIRE(lpathconf(path, _PC_SYMLINK_MAX) != -1); check_audit(fds, successreg, pipefd); } ATF_TC_CLEANUP(lpathconf_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lpathconf_failure); ATF_TC_HEAD(lpathconf_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "lpathconf(2) call"); } ATF_TC_BODY(lpathconf_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, lpathconf(errpath, _PC_SYMLINK_MAX)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(lpathconf_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fpathconf_success); ATF_TC_HEAD(fpathconf_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fpathconf(2) call"); } ATF_TC_BODY(fpathconf_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fpathconf.*%d.*success", pid); /* File needs to exist to call fpathconf(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); /* Get the maximum number of bytes of filename */ ATF_REQUIRE(fpathconf(filedesc, _PC_NAME_MAX) != -1); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fpathconf_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fpathconf_failure); ATF_TC_HEAD(fpathconf_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fpathconf(2) call"); } ATF_TC_BODY(fpathconf_failure, tc) { FILE *pipefd = setup(fds, auclass); const char *regex = "fpathconf.*return,failure : Bad file descriptor"; /* Failure reason: Bad file descriptor */ ATF_REQUIRE_EQ(-1, fpathconf(-1, _PC_NAME_MAX)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fpathconf_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_get_file_success); ATF_TC_HEAD(extattr_get_file_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_get_file(2) call"); } ATF_TC_BODY(extattr_get_file_success, tc) { /* File needs to exist to call extattr_get_file(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); /* Set an extended attribute to be retrieved later on */ ATF_REQUIRE_EQ(sizeof(buff), extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_get_file.*%s.*%s.*return,success", path, name); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(sizeof(buff), extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(extattr_get_file_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_get_file_failure); ATF_TC_HEAD(extattr_get_file_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_get_file(2) call"); } ATF_TC_BODY(extattr_get_file_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_get_file.*%s.*%s.*failure", path, name); FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_get_file_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_get_fd_success); ATF_TC_HEAD(extattr_get_fd_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_get_fd(2) call"); } ATF_TC_BODY(extattr_get_fd_success, tc) { /* File needs to exist to call extattr_get_fd(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); /* Set an extended attribute to be retrieved later on */ ATF_REQUIRE_EQ(sizeof(buff), extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_get_fd.*%s.*return,success", name); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(sizeof(buff), extattr_get_fd(filedesc, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(extattr_get_fd_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_get_fd_failure); ATF_TC_HEAD(extattr_get_fd_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_get_fd(2) call"); } ATF_TC_BODY(extattr_get_fd_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_get_fd.*%s.*return,failure : Bad file descriptor", name); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, extattr_get_fd(-1, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_get_fd_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_get_link_success); ATF_TC_HEAD(extattr_get_link_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_get_link(2) call"); } ATF_TC_BODY(extattr_get_link_success, tc) { /* Symbolic link needs to exist to call extattr_get_link(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); /* Set an extended attribute to be retrieved later on */ ATF_REQUIRE_EQ(sizeof(buff), extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_get_link.*%s.*%s.*return,success", path, name); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(sizeof(buff), extattr_get_link(path, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_get_link_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_get_link_failure); ATF_TC_HEAD(extattr_get_link_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_get_link(2) call"); } ATF_TC_BODY(extattr_get_link_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_get_link.*%s.*%s.*failure", path, name); FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, extattr_get_link(path, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_get_link_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_list_file_success); ATF_TC_HEAD(extattr_list_file_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_list_file(2) call"); } ATF_TC_BODY(extattr_list_file_success, tc) { int readbuff; /* File needs to exist to call extattr_list_file(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((readbuff = extattr_list_file(path, EXTATTR_NAMESPACE_USER, NULL, 0)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_list_file.*%s.*return,success,%d", path, readbuff); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_list_file_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_list_file_failure); ATF_TC_HEAD(extattr_list_file_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_list_file(2) call"); } ATF_TC_BODY(extattr_list_file_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_list_file.*%s.*return,failure", path); FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, extattr_list_file(path, EXTATTR_NAMESPACE_USER, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_list_file_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_list_fd_success); ATF_TC_HEAD(extattr_list_fd_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_list_fd(2) call"); } ATF_TC_BODY(extattr_list_fd_success, tc) { int readbuff; /* File needs to exist to call extattr_list_fd(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((readbuff = extattr_list_fd(filedesc, EXTATTR_NAMESPACE_USER, NULL, 0)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_list_fd.*return,success,%d", readbuff); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(extattr_list_fd_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_list_fd_failure); ATF_TC_HEAD(extattr_list_fd_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_list_fd(2) call"); } ATF_TC_BODY(extattr_list_fd_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_list_fd.*return,failure : Bad file descriptor"); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, extattr_list_fd(-1, EXTATTR_NAMESPACE_USER, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_list_fd_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_list_link_success); ATF_TC_HEAD(extattr_list_link_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_list_link(2) call"); } ATF_TC_BODY(extattr_list_link_success, tc) { int readbuff; /* Symbolic link needs to exist to call extattr_list_link(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((readbuff = extattr_list_link(path, EXTATTR_NAMESPACE_USER, NULL, 0)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_list_link.*%s.*return,success,%d", path, readbuff); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_list_link_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_list_link_failure); ATF_TC_HEAD(extattr_list_link_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_list_link(2) call"); } ATF_TC_BODY(extattr_list_link_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_list_link.*%s.*failure", path); FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, extattr_list_link(path, EXTATTR_NAMESPACE_USER, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_list_link_failure, tc) { cleanup(); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, stat_success); ATF_TP_ADD_TC(tp, stat_failure); ATF_TP_ADD_TC(tp, lstat_success); ATF_TP_ADD_TC(tp, lstat_failure); ATF_TP_ADD_TC(tp, fstat_success); ATF_TP_ADD_TC(tp, fstat_failure); ATF_TP_ADD_TC(tp, fstatat_success); ATF_TP_ADD_TC(tp, fstatat_failure); ATF_TP_ADD_TC(tp, statfs_success); ATF_TP_ADD_TC(tp, statfs_failure); ATF_TP_ADD_TC(tp, fstatfs_success); ATF_TP_ADD_TC(tp, fstatfs_failure); ATF_TP_ADD_TC(tp, getfsstat_success); ATF_TP_ADD_TC(tp, getfsstat_failure); ATF_TP_ADD_TC(tp, lgetfh_success); ATF_TP_ADD_TC(tp, lgetfh_failure); ATF_TP_ADD_TC(tp, fhopen_success); ATF_TP_ADD_TC(tp, fhopen_failure); ATF_TP_ADD_TC(tp, fhstat_success); ATF_TP_ADD_TC(tp, fhstat_failure); ATF_TP_ADD_TC(tp, fhstatfs_success); ATF_TP_ADD_TC(tp, fhstatfs_failure); ATF_TP_ADD_TC(tp, access_success); ATF_TP_ADD_TC(tp, access_failure); ATF_TP_ADD_TC(tp, eaccess_success); ATF_TP_ADD_TC(tp, eaccess_failure); ATF_TP_ADD_TC(tp, faccessat_success); ATF_TP_ADD_TC(tp, faccessat_failure); ATF_TP_ADD_TC(tp, pathconf_success); ATF_TP_ADD_TC(tp, pathconf_failure); ATF_TP_ADD_TC(tp, lpathconf_success); ATF_TP_ADD_TC(tp, lpathconf_failure); ATF_TP_ADD_TC(tp, fpathconf_success); ATF_TP_ADD_TC(tp, fpathconf_failure); ATF_TP_ADD_TC(tp, extattr_get_file_success); ATF_TP_ADD_TC(tp, extattr_get_file_failure); ATF_TP_ADD_TC(tp, extattr_get_fd_success); ATF_TP_ADD_TC(tp, extattr_get_fd_failure); ATF_TP_ADD_TC(tp, extattr_get_link_success); ATF_TP_ADD_TC(tp, extattr_get_link_failure); ATF_TP_ADD_TC(tp, extattr_list_file_success); ATF_TP_ADD_TC(tp, extattr_list_file_failure); ATF_TP_ADD_TC(tp, extattr_list_fd_success); ATF_TP_ADD_TC(tp, extattr_list_fd_failure); ATF_TP_ADD_TC(tp, extattr_list_link_success); ATF_TP_ADD_TC(tp, extattr_list_link_failure); return (atf_no_error()); } Index: head/tests/sys/audit/file-attribute-modify.c =================================================================== --- head/tests/sys/audit/file-attribute-modify.c (revision 336603) +++ head/tests/sys/audit/file-attribute-modify.c (revision 336604) @@ -1,1387 +1,1381 @@ /*- * Copyright (c) 2018 Aniket Pandey * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include #include "utils.h" static pid_t pid; static uid_t uid = -1; static gid_t gid = -1; static int filedesc, retval; static struct pollfd fds[1]; static mode_t mode = 0777; static char extregex[80]; static char buff[] = "ezio"; static const char *auclass = "fm"; static const char *name = "authorname"; static const char *path = "fileforaudit"; static const char *errpath = "adirhasnoname/fileforaudit"; static const char *successreg = "fileforaudit.*return,success"; static const char *failurereg = "fileforaudit.*return,failure"; ATF_TC_WITH_CLEANUP(flock_success); ATF_TC_HEAD(flock_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "flock(2) call"); } ATF_TC_BODY(flock_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "flock.*%d.*return,success", pid); /* File needs to exist to call flock(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, flock(filedesc, LOCK_SH)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(flock_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(flock_failure); ATF_TC_HEAD(flock_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "flock(2) call"); } ATF_TC_BODY(flock_failure, tc) { const char *regex = "flock.*return,failure : Bad file descriptor"; FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, flock(-1, LOCK_SH)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(flock_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fcntl_success); ATF_TC_HEAD(fcntl_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fcntl(2) call"); } ATF_TC_BODY(fcntl_success, tc) { int flagstatus; /* File needs to exist to call fcntl(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); /* Retrieve the status flags of 'filedesc' and store it in flagstatus */ ATF_REQUIRE((flagstatus = fcntl(filedesc, F_GETFL, 0)) != -1); snprintf(extregex, sizeof(extregex), "fcntl.*return,success,%d", flagstatus); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fcntl_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fcntl_failure); ATF_TC_HEAD(fcntl_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fcntl(2) call"); } ATF_TC_BODY(fcntl_failure, tc) { const char *regex = "fcntl.*return,failure : Bad file descriptor"; FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, fcntl(-1, F_GETFL, 0)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fcntl_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fsync_success); ATF_TC_HEAD(fsync_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fsync(2) call"); } ATF_TC_BODY(fsync_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fsync.*%d.*return,success", pid); /* File needs to exist to call fsync(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fsync(filedesc)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fsync_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fsync_failure); ATF_TC_HEAD(fsync_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fsync(2) call"); } ATF_TC_BODY(fsync_failure, tc) { const char *regex = "fsync.*return,failure : Bad file descriptor"; FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, fsync(-1)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fsync_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chmod_success); ATF_TC_HEAD(chmod_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "chmod(2) call"); } ATF_TC_BODY(chmod_success, tc) { /* File needs to exist to call chmod(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, chmod(path, mode)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(chmod_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chmod_failure); ATF_TC_HEAD(chmod_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "chmod(2) call"); } ATF_TC_BODY(chmod_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, chmod(errpath, mode)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(chmod_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchmod_success); ATF_TC_HEAD(fchmod_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fchmod(2) call"); } ATF_TC_BODY(fchmod_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fchmod.*%d.*return,success", pid); /* File needs to exist to call fchmod(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fchmod(filedesc, mode)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fchmod_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchmod_failure); ATF_TC_HEAD(fchmod_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fchmod(2) call"); } ATF_TC_BODY(fchmod_failure, tc) { const char *regex = "fchmod.*return,failure : Bad file descriptor"; FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, fchmod(-1, mode)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fchmod_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lchmod_success); ATF_TC_HEAD(lchmod_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "lchmod(2) call"); } ATF_TC_BODY(lchmod_success, tc) { /* Symbolic link needs to exist to call lchmod(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, lchmod(path, mode)); check_audit(fds, successreg, pipefd); } ATF_TC_CLEANUP(lchmod_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lchmod_failure); ATF_TC_HEAD(lchmod_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "lchmod(2) call"); } ATF_TC_BODY(lchmod_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, lchmod(errpath, mode)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(lchmod_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchmodat_success); ATF_TC_HEAD(fchmodat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fchmodat(2) call"); } ATF_TC_BODY(fchmodat_success, tc) { /* File needs to exist to call fchmodat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fchmodat(AT_FDCWD, path, mode, 0)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(fchmodat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchmodat_failure); ATF_TC_HEAD(fchmodat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fchmodat(2) call"); } ATF_TC_BODY(fchmodat_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, fchmodat(AT_FDCWD, errpath, mode, 0)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(fchmodat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chown_success); ATF_TC_HEAD(chown_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "chown(2) call"); } ATF_TC_BODY(chown_success, tc) { /* File needs to exist to call chown(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, chown(path, uid, gid)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(chown_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chown_failure); ATF_TC_HEAD(chown_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "chown(2) call"); } ATF_TC_BODY(chown_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, chown(errpath, uid, gid)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(chown_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchown_success); ATF_TC_HEAD(fchown_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fchown(2) call"); } ATF_TC_BODY(fchown_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fchown.*%d.*return,success", pid); /* File needs to exist to call fchown(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fchown(filedesc, uid, gid)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fchown_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchown_failure); ATF_TC_HEAD(fchown_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fchown(2) call"); } ATF_TC_BODY(fchown_failure, tc) { const char *regex = "fchown.*return,failure : Bad file descriptor"; FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, fchown(-1, uid, gid)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fchown_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lchown_success); ATF_TC_HEAD(lchown_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "lchown(2) call"); } ATF_TC_BODY(lchown_success, tc) { /* Symbolic link needs to exist to call lchown(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, lchown(path, uid, gid)); check_audit(fds, successreg, pipefd); } ATF_TC_CLEANUP(lchown_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lchown_failure); ATF_TC_HEAD(lchown_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "lchown(2) call"); } ATF_TC_BODY(lchown_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: Symbolic link does not exist */ ATF_REQUIRE_EQ(-1, lchown(errpath, uid, gid)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(lchown_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchownat_success); ATF_TC_HEAD(fchownat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fchownat(2) call"); } ATF_TC_BODY(fchownat_success, tc) { /* File needs to exist to call fchownat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fchownat(AT_FDCWD, path, uid, gid, 0)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(fchownat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchownat_failure); ATF_TC_HEAD(fchownat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fchownat(2) call"); } ATF_TC_BODY(fchownat_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, fchownat(AT_FDCWD, errpath, uid, gid, 0)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(fchownat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chflags_success); ATF_TC_HEAD(chflags_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "chflags(2) call"); } ATF_TC_BODY(chflags_success, tc) { /* File needs to exist to call chflags(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, chflags(path, UF_OFFLINE)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(chflags_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chflags_failure); ATF_TC_HEAD(chflags_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "chflags(2) call"); } ATF_TC_BODY(chflags_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, chflags(errpath, UF_OFFLINE)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(chflags_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchflags_success); ATF_TC_HEAD(fchflags_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "fchflags(2) call"); } ATF_TC_BODY(fchflags_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "fchflags.*%d.*ret.*success", pid); /* File needs to exist to call fchflags(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, fchflags(filedesc, UF_OFFLINE)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(fchflags_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(fchflags_failure); ATF_TC_HEAD(fchflags_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "fchflags(2) call"); } ATF_TC_BODY(fchflags_failure, tc) { const char *regex = "fchflags.*return,failure : Bad file descriptor"; FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, fchflags(-1, UF_OFFLINE)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(fchflags_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lchflags_success); ATF_TC_HEAD(lchflags_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "lchflags(2) call"); } ATF_TC_BODY(lchflags_success, tc) { /* Symbolic link needs to exist to call lchflags(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, lchflags(path, UF_OFFLINE)); check_audit(fds, successreg, pipefd); } ATF_TC_CLEANUP(lchflags_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lchflags_failure); ATF_TC_HEAD(lchflags_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "lchflags(2) call"); } ATF_TC_BODY(lchflags_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: Symbolic link does not exist */ ATF_REQUIRE_EQ(-1, lchflags(errpath, UF_OFFLINE)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(lchflags_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chflagsat_success); ATF_TC_HEAD(chflagsat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "chflagsat(2) call"); } ATF_TC_BODY(chflagsat_success, tc) { - /* BSM conversion requested for unknown event 43209 */ - atf_tc_expect_fail("PR 228374: chflagsat(2) does not get audited in success mode"); - /* File needs to exist to call chflagsat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, chflagsat(AT_FDCWD, path, SF_IMMUTABLE, 0)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(chflagsat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(chflagsat_failure); ATF_TC_HEAD(chflagsat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "chflagsat(2) call"); } ATF_TC_BODY(chflagsat_failure, tc) { - /* BSM conversion requested for unknown event 43209 */ - atf_tc_expect_fail("PR 228374: chflagsat(2) does not get audited in failure mode"); - FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, chflagsat(AT_FDCWD, errpath, SF_IMMUTABLE, 0)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(chflagsat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(utimes_success); ATF_TC_HEAD(utimes_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "utimes(2) call"); } ATF_TC_BODY(utimes_success, tc) { /* File needs to exist to call utimes(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, utimes(path, NULL)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(utimes_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(utimes_failure); ATF_TC_HEAD(utimes_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "utimes(2) call"); } ATF_TC_BODY(utimes_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, utimes(errpath, NULL)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(utimes_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(futimes_success); ATF_TC_HEAD(futimes_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "futimes(2) call"); } ATF_TC_BODY(futimes_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "futimes.*%d.*ret.*success", pid); /* File needs to exist to call futimes(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, futimes(filedesc, NULL)); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(futimes_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(futimes_failure); ATF_TC_HEAD(futimes_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "futimes(2) call"); } ATF_TC_BODY(futimes_failure, tc) { const char *regex = "futimes.*return,failure : Bad file descriptor"; FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, futimes(-1, NULL)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(futimes_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lutimes_success); ATF_TC_HEAD(lutimes_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "lutimes(2) call"); } ATF_TC_BODY(lutimes_success, tc) { /* Symbolic link needs to exist to call lutimes(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, lutimes(path, NULL)); check_audit(fds, successreg, pipefd); } ATF_TC_CLEANUP(lutimes_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(lutimes_failure); ATF_TC_HEAD(lutimes_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "lutimes(2) call"); } ATF_TC_BODY(lutimes_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, lutimes(errpath, NULL)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(lutimes_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(futimesat_success); ATF_TC_HEAD(futimesat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "futimesat(2) call"); } ATF_TC_BODY(futimesat_success, tc) { /* File needs to exist to call futimesat(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, futimesat(AT_FDCWD, path, NULL)); check_audit(fds, successreg, pipefd); close(filedesc); } ATF_TC_CLEANUP(futimesat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(futimesat_failure); ATF_TC_HEAD(futimesat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "futimesat(2) call"); } ATF_TC_BODY(futimesat_failure, tc) { FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, futimesat(AT_FDCWD, errpath, NULL)); check_audit(fds, failurereg, pipefd); } ATF_TC_CLEANUP(futimesat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(mprotect_success); ATF_TC_HEAD(mprotect_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "mprotect(2) call"); } ATF_TC_BODY(mprotect_success, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "mprotect.*%d.*ret.*success", pid); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, mprotect(NULL, 0, PROT_NONE)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(mprotect_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(mprotect_failure); ATF_TC_HEAD(mprotect_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "mprotect(2) call"); } ATF_TC_BODY(mprotect_failure, tc) { const char *regex = "mprotect.*return,failure : Invalid argument"; FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, mprotect((void *)SIZE_MAX, -1, PROT_NONE)); check_audit(fds, regex, pipefd); } ATF_TC_CLEANUP(mprotect_failure, tc) { cleanup(); } /* * undelete(2) only works on whiteout files in union file system. Hence, no * test case for successful invocation. */ ATF_TC_WITH_CLEANUP(undelete_failure); ATF_TC_HEAD(undelete_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "undelete(2) call"); } ATF_TC_BODY(undelete_failure, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "undelete.*%d.*ret.*failure", pid); FILE *pipefd = setup(fds, auclass); /* Failure reason: File does not exist */ ATF_REQUIRE_EQ(-1, undelete(errpath)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(undelete_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_set_file_success); ATF_TC_HEAD(extattr_set_file_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_set_file(2) call"); } ATF_TC_BODY(extattr_set_file_success, tc) { /* File needs to exist to call extattr_set_file(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_set_file.*%s.*%s.*return,success", path, name); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(sizeof(buff), extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(extattr_set_file_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_set_file_failure); ATF_TC_HEAD(extattr_set_file_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_set_file(2) call"); } ATF_TC_BODY(extattr_set_file_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_set_file.*%s.*%s.*failure", path, name); FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_set_file_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_set_fd_success); ATF_TC_HEAD(extattr_set_fd_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_set_fd(2) call"); } ATF_TC_BODY(extattr_set_fd_success, tc) { /* File needs to exist to call extattr_set_fd(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_set_fd.*%s.*return,success", name); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(sizeof(buff), extattr_set_fd(filedesc, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(extattr_set_fd_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_set_fd_failure); ATF_TC_HEAD(extattr_set_fd_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_set_fd(2) call"); } ATF_TC_BODY(extattr_set_fd_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_set_fd.*%s.*return,failure : Bad file descriptor", name); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, extattr_set_fd(-1, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_set_fd_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_set_link_success); ATF_TC_HEAD(extattr_set_link_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_set_link(2) call"); } ATF_TC_BODY(extattr_set_link_success, tc) { /* Symbolic link needs to exist to call extattr_set_link(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_set_link.*%s.*%s.*return,success", path, name); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(sizeof(buff), extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_set_link_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_set_link_failure); ATF_TC_HEAD(extattr_set_link_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_set_link(2) call"); } ATF_TC_BODY(extattr_set_link_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_set_link.*%s.*%s.*failure", path, name); FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_set_link_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_delete_file_success); ATF_TC_HEAD(extattr_delete_file_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_delete_file(2) call"); } ATF_TC_BODY(extattr_delete_file_success, tc) { /* File needs to exist to call extattr_delete_file(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); ATF_REQUIRE_EQ(sizeof(buff), extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((retval = extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_delete_file.*%s.*return,success,%d", path, retval); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(extattr_delete_file_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_delete_file_failure); ATF_TC_HEAD(extattr_delete_file_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_delete_file(2) call"); } ATF_TC_BODY(extattr_delete_file_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_delete_file.*%s.*return,failure", path); FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_delete_file_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_delete_fd_success); ATF_TC_HEAD(extattr_delete_fd_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_delete_fd(2) call"); } ATF_TC_BODY(extattr_delete_fd_success, tc) { /* File needs to exist to call extattr_delete_fd(2) */ ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); ATF_REQUIRE_EQ(sizeof(buff), extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((retval = extattr_delete_fd(filedesc, EXTATTR_NAMESPACE_USER, name)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_delete_fd.*return,success,%d", retval); check_audit(fds, extregex, pipefd); close(filedesc); } ATF_TC_CLEANUP(extattr_delete_fd_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_delete_fd_failure); ATF_TC_HEAD(extattr_delete_fd_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_delete_fd(2) call"); } ATF_TC_BODY(extattr_delete_fd_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_delete_fd.*return,failure : Bad file descriptor"); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid file descriptor */ ATF_REQUIRE_EQ(-1, extattr_delete_fd(-1, EXTATTR_NAMESPACE_USER, name)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_delete_fd_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_delete_link_success); ATF_TC_HEAD(extattr_delete_link_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "extattr_delete_link(2) call"); } ATF_TC_BODY(extattr_delete_link_success, tc) { /* Symbolic link needs to exist to call extattr_delete_link(2) */ ATF_REQUIRE_EQ(0, symlink("symlink", path)); ATF_REQUIRE_EQ(sizeof(buff), extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, buff, sizeof(buff))); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((retval = extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name)) != -1); /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_delete_link.*%s.*return,success,%d", path, retval); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_delete_link_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(extattr_delete_link_failure); ATF_TC_HEAD(extattr_delete_link_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "extattr_delete_link(2) call"); } ATF_TC_BODY(extattr_delete_link_failure, tc) { /* Prepare the regex to be checked in the audit record */ snprintf(extregex, sizeof(extregex), "extattr_delete_link.*%s.*failure", path); FILE *pipefd = setup(fds, auclass); /* Failure reason: symbolic link does not exist */ ATF_REQUIRE_EQ(-1, extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(extattr_delete_link_failure, tc) { cleanup(); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, flock_success); ATF_TP_ADD_TC(tp, flock_failure); ATF_TP_ADD_TC(tp, fcntl_success); ATF_TP_ADD_TC(tp, fcntl_failure); ATF_TP_ADD_TC(tp, fsync_success); ATF_TP_ADD_TC(tp, fsync_failure); ATF_TP_ADD_TC(tp, chmod_success); ATF_TP_ADD_TC(tp, chmod_failure); ATF_TP_ADD_TC(tp, fchmod_success); ATF_TP_ADD_TC(tp, fchmod_failure); ATF_TP_ADD_TC(tp, lchmod_success); ATF_TP_ADD_TC(tp, lchmod_failure); ATF_TP_ADD_TC(tp, fchmodat_success); ATF_TP_ADD_TC(tp, fchmodat_failure); ATF_TP_ADD_TC(tp, chown_success); ATF_TP_ADD_TC(tp, chown_failure); ATF_TP_ADD_TC(tp, fchown_success); ATF_TP_ADD_TC(tp, fchown_failure); ATF_TP_ADD_TC(tp, lchown_success); ATF_TP_ADD_TC(tp, lchown_failure); ATF_TP_ADD_TC(tp, fchownat_success); ATF_TP_ADD_TC(tp, fchownat_failure); ATF_TP_ADD_TC(tp, chflags_success); ATF_TP_ADD_TC(tp, chflags_failure); ATF_TP_ADD_TC(tp, fchflags_success); ATF_TP_ADD_TC(tp, fchflags_failure); ATF_TP_ADD_TC(tp, lchflags_success); ATF_TP_ADD_TC(tp, lchflags_failure); ATF_TP_ADD_TC(tp, chflagsat_success); ATF_TP_ADD_TC(tp, chflagsat_failure); ATF_TP_ADD_TC(tp, utimes_success); ATF_TP_ADD_TC(tp, utimes_failure); ATF_TP_ADD_TC(tp, futimes_success); ATF_TP_ADD_TC(tp, futimes_failure); ATF_TP_ADD_TC(tp, lutimes_success); ATF_TP_ADD_TC(tp, lutimes_failure); ATF_TP_ADD_TC(tp, futimesat_success); ATF_TP_ADD_TC(tp, futimesat_failure); ATF_TP_ADD_TC(tp, mprotect_success); ATF_TP_ADD_TC(tp, mprotect_failure); ATF_TP_ADD_TC(tp, undelete_failure); ATF_TP_ADD_TC(tp, extattr_set_file_success); ATF_TP_ADD_TC(tp, extattr_set_file_failure); ATF_TP_ADD_TC(tp, extattr_set_fd_success); ATF_TP_ADD_TC(tp, extattr_set_fd_failure); ATF_TP_ADD_TC(tp, extattr_set_link_success); ATF_TP_ADD_TC(tp, extattr_set_link_failure); ATF_TP_ADD_TC(tp, extattr_delete_file_success); ATF_TP_ADD_TC(tp, extattr_delete_file_failure); ATF_TP_ADD_TC(tp, extattr_delete_fd_success); ATF_TP_ADD_TC(tp, extattr_delete_fd_failure); ATF_TP_ADD_TC(tp, extattr_delete_link_success); ATF_TP_ADD_TC(tp, extattr_delete_link_failure); return (atf_no_error()); } Index: head/tests/sys/audit/network.c =================================================================== --- head/tests/sys/audit/network.c (revision 336603) +++ head/tests/sys/audit/network.c (revision 336604) @@ -1,1189 +1,1183 @@ /*- * Copyright (c) 2018 Aniket Pandey * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include "utils.h" #define MAX_DATA 128 #define SERVER_PATH "server" static pid_t pid; static mode_t mode = 0777; static int sockfd, sockfd2, connectfd; static ssize_t data_bytes; static socklen_t len = sizeof(struct sockaddr_un); static struct iovec io1, io2; static struct pollfd fds[1]; static struct sockaddr_un server; static struct msghdr sendbuf, recvbuf; static char extregex[MAX_DATA]; static char data[MAX_DATA]; static char msgbuff[MAX_DATA] = "This message does not exist"; static const char *auclass = "nt"; static const char *path = "fileforaudit"; static const char *nosupregex = "return,failure : Address family " "not supported by protocol family"; static const char *invalregex = "return,failure : Bad file descriptor"; /* * Initialize iovec structure to be used as a field of struct msghdr */ static void init_iov(struct iovec *io, char msgbuf[], int datalen) { io->iov_base = msgbuf; io->iov_len = datalen; } /* * Initialize msghdr structure for communication via datagram sockets */ static void init_msghdr(struct msghdr *hdrbuf, struct iovec *io, struct sockaddr_un *addr) { socklen_t length; bzero(hdrbuf, sizeof(*hdrbuf)); length = (socklen_t)sizeof(struct sockaddr_un); hdrbuf->msg_name = addr; hdrbuf->msg_namelen = length; hdrbuf->msg_iov = io; hdrbuf->msg_iovlen = 1; } /* * Variadic function to close socket descriptors */ static void close_sockets(int count, ...) { int sockd; va_list socklist; va_start(socklist, count); for (sockd = 0; sockd < count; sockd++) { close(va_arg(socklist, int)); } va_end(socklist); } /* * Assign local filesystem address to a Unix domain socket */ static void assign_address(struct sockaddr_un *serveraddr) { memset(serveraddr, 0, sizeof(*serveraddr)); serveraddr->sun_family = AF_UNIX; strcpy(serveraddr->sun_path, SERVER_PATH); } ATF_TC_WITH_CLEANUP(socket_success); ATF_TC_HEAD(socket_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "socket(2) call"); } ATF_TC_BODY(socket_success, tc) { FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); /* Check the presence of sockfd in audit record */ snprintf(extregex, sizeof(extregex), "socket.*ret.*success,%d", sockfd); check_audit(fds, extregex, pipefd); close(sockfd); } ATF_TC_CLEANUP(socket_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(socket_failure); ATF_TC_HEAD(socket_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "socket(2) call"); } ATF_TC_BODY(socket_failure, tc) { snprintf(extregex, sizeof(extregex), "socket.*%s", nosupregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Unsupported value of 'domain' argument: 0 */ ATF_REQUIRE_EQ(-1, socket(0, SOCK_STREAM, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(socket_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(socketpair_success); ATF_TC_HEAD(socketpair_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "socketpair(2) call"); } ATF_TC_BODY(socketpair_success, tc) { int sv[2]; FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, socketpair(PF_UNIX, SOCK_STREAM, 0, sv)); /* Check for 0x0 (argument 3: default protocol) in the audit record */ snprintf(extregex, sizeof(extregex), "socketpair.*0x0.*return,success"); check_audit(fds, extregex, pipefd); close_sockets(2, sv[0], sv[1]); } ATF_TC_CLEANUP(socketpair_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(socketpair_failure); ATF_TC_HEAD(socketpair_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "socketpair(2) call"); } ATF_TC_BODY(socketpair_failure, tc) { snprintf(extregex, sizeof(extregex), "socketpair.*%s", nosupregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Unsupported value of 'domain' argument: 0 */ ATF_REQUIRE_EQ(-1, socketpair(0, SOCK_STREAM, 0, NULL)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(socketpair_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(setsockopt_success); ATF_TC_HEAD(setsockopt_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "setsockopt(2) call"); } ATF_TC_BODY(setsockopt_success, tc) { int tr = 1; ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); /* Check the presence of sockfd in audit record */ snprintf(extregex, sizeof(extregex), "setsockopt.*0x%x.*return,success", sockfd); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &tr, sizeof(int))); check_audit(fds, extregex, pipefd); close(sockfd); } ATF_TC_CLEANUP(setsockopt_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(setsockopt_failure); ATF_TC_HEAD(setsockopt_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "setsockopt(2) call"); } ATF_TC_BODY(setsockopt_failure, tc) { snprintf(extregex, sizeof(extregex), "setsockopt.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, setsockopt(-1, SOL_SOCKET, 0, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(setsockopt_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(bind_success); ATF_TC_HEAD(bind_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "bind(2) call"); } ATF_TC_BODY(bind_success, tc) { assign_address(&server); /* Preliminary socket setup */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); /* Check the presence of AF_UNIX address path in audit record */ snprintf(extregex, sizeof(extregex), "bind.*unix.*%s.*return,success", SERVER_PATH); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); close(sockfd); } ATF_TC_CLEANUP(bind_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(bind_failure); ATF_TC_HEAD(bind_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "bind(2) call"); } ATF_TC_BODY(bind_failure, tc) { assign_address(&server); /* Check the presence of AF_UNIX path in audit record */ snprintf(extregex, sizeof(extregex), "bind.*%s.*return,failure", SERVER_PATH); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, bind(0, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(bind_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(bindat_success); ATF_TC_HEAD(bindat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "bindat(2) call"); } ATF_TC_BODY(bindat_success, tc) { assign_address(&server); /* Preliminary socket setup */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); /* Check the presence of socket descriptor in audit record */ snprintf(extregex, sizeof(extregex), "bindat.*0x%x.*return,success", sockfd); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, bindat(AT_FDCWD, sockfd, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); close(sockfd); } ATF_TC_CLEANUP(bindat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(bindat_failure); ATF_TC_HEAD(bindat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "bindat(2) call"); } ATF_TC_BODY(bindat_failure, tc) { assign_address(&server); snprintf(extregex, sizeof(extregex), "bindat.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, bindat(AT_FDCWD, -1, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(bindat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(listen_success); ATF_TC_HEAD(listen_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "listen(2) call"); } ATF_TC_BODY(listen_success, tc) { assign_address(&server); /* Preliminary socket setup */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); /* Check the presence of socket descriptor in the audit record */ snprintf(extregex, sizeof(extregex), "listen.*0x%x.*return,success", sockfd); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, listen(sockfd, 1)); check_audit(fds, extregex, pipefd); close(sockfd); } ATF_TC_CLEANUP(listen_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(listen_failure); ATF_TC_HEAD(listen_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "listen(2) call"); } ATF_TC_BODY(listen_failure, tc) { snprintf(extregex, sizeof(extregex), "listen.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, listen(-1, 1)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(listen_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(connect_success); ATF_TC_HEAD(connect_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "connect(2) call"); } ATF_TC_BODY(connect_success, tc) { assign_address(&server); /* Setup a server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); ATF_REQUIRE_EQ(0, listen(sockfd, 1)); /* Set up "blocking" client socket */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); /* Audit record must contain AF_UNIX address path & sockfd2 */ snprintf(extregex, sizeof(extregex), "connect.*0x%x.*%s.*success", sockfd2, SERVER_PATH); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(2, sockfd, sockfd2); } ATF_TC_CLEANUP(connect_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(connect_failure); ATF_TC_HEAD(connect_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "connect(2) call"); } ATF_TC_BODY(connect_failure, tc) { assign_address(&server); /* Audit record must contain AF_UNIX address path */ snprintf(extregex, sizeof(extregex), "connect.*%s.*return,failure", SERVER_PATH); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, connect(-1, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(connect_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(connectat_success); ATF_TC_HEAD(connectat_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "connectat(2) call"); } ATF_TC_BODY(connectat_success, tc) { assign_address(&server); /* Setup a server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); ATF_REQUIRE_EQ(0, listen(sockfd, 1)); /* Set up "blocking" client socket */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); /* Audit record must contain sockfd2 */ snprintf(extregex, sizeof(extregex), "connectat.*0x%x.*return,success", sockfd2); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, connectat(AT_FDCWD, sockfd2, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(2, sockfd, sockfd2); } ATF_TC_CLEANUP(connectat_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(connectat_failure); ATF_TC_HEAD(connectat_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "connectat(2) call"); } ATF_TC_BODY(connectat_failure, tc) { assign_address(&server); snprintf(extregex, sizeof(extregex), "connectat.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, connectat(AT_FDCWD, -1, (struct sockaddr *)&server, len)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(connectat_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(accept_success); ATF_TC_HEAD(accept_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "accept(2) call"); } ATF_TC_BODY(accept_success, tc) { assign_address(&server); /* Setup a server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); ATF_REQUIRE_EQ(0, listen(sockfd, 1)); /* Set up "blocking" client socket */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); /* Audit record must contain connectfd & sockfd */ snprintf(extregex, sizeof(extregex), "accept.*0x%x.*return,success,%d", sockfd, connectfd); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(3, sockfd, sockfd2, connectfd); } ATF_TC_CLEANUP(accept_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(accept_failure); ATF_TC_HEAD(accept_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "accept(2) call"); } ATF_TC_BODY(accept_failure, tc) { snprintf(extregex, sizeof(extregex), "accept.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, accept(-1, NULL, NULL)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(accept_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(send_success); ATF_TC_HEAD(send_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "send(2) call"); } ATF_TC_BODY(send_success, tc) { assign_address(&server); /* Setup a server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); ATF_REQUIRE_EQ(0, listen(sockfd, 1)); /* Set up "blocking" client and connect with non-blocking server */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); /* Send a sample message to the connected socket */ FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((data_bytes = send(sockfd2, msgbuff, strlen(msgbuff), 0)) != -1); /* Audit record must contain sockfd2 and data_bytes */ snprintf(extregex, sizeof(extregex), "send.*0x%x.*return,success,%zd", sockfd2, data_bytes); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(3, sockfd, sockfd2, connectfd); } ATF_TC_CLEANUP(send_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(send_failure); ATF_TC_HEAD(send_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "send(2) call"); } ATF_TC_BODY(send_failure, tc) { snprintf(extregex, sizeof(extregex), "send.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, send(-1, NULL, 0, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(send_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(recv_success); ATF_TC_HEAD(recv_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "recv(2) call"); } ATF_TC_BODY(recv_success, tc) { assign_address(&server); /* Setup a server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); ATF_REQUIRE_EQ(0, listen(sockfd, 1)); /* Set up "blocking" client and connect with non-blocking server */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); /* Send a sample message to the connected socket */ ATF_REQUIRE(send(sockfd2, msgbuff, strlen(msgbuff), 0) != -1); /* Receive data once connectfd is ready for reading */ FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((data_bytes = recv(connectfd, data, MAX_DATA, 0)) != 0); /* Audit record must contain connectfd and data_bytes */ snprintf(extregex, sizeof(extregex), "recv.*0x%x.*return,success,%zd", connectfd, data_bytes); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(3, sockfd, sockfd2, connectfd); } ATF_TC_CLEANUP(recv_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(recv_failure); ATF_TC_HEAD(recv_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "recv(2) call"); } ATF_TC_BODY(recv_failure, tc) { snprintf(extregex, sizeof(extregex), "recv.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, recv(-1, NULL, 0, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(recv_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(sendto_success); ATF_TC_HEAD(sendto_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "sendto(2) call"); } ATF_TC_BODY(sendto_success, tc) { assign_address(&server); /* Setup a server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); /* Set up client socket to be used for sending the data */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); /* Send a sample message to server's address */ FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((data_bytes = sendto(sockfd2, msgbuff, strlen(msgbuff), 0, (struct sockaddr *)&server, len)) != -1); /* Audit record must contain sockfd2 and data_bytes */ snprintf(extregex, sizeof(extregex), "sendto.*0x%x.*return,success,%zd", sockfd2, data_bytes); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(2, sockfd, sockfd2); } ATF_TC_CLEANUP(sendto_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(sendto_failure); ATF_TC_HEAD(sendto_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "sendto(2) call"); } ATF_TC_BODY(sendto_failure, tc) { snprintf(extregex, sizeof(extregex), "sendto.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, sendto(-1, NULL, 0, 0, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(sendto_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(recvfrom_success); ATF_TC_HEAD(recvfrom_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "recvfrom(2) call"); } ATF_TC_BODY(recvfrom_success, tc) { assign_address(&server); /* Setup a server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); /* Set up client socket to be used for sending the data */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); ATF_REQUIRE(sendto(sockfd2, msgbuff, strlen(msgbuff), 0, (struct sockaddr *)&server, len) != -1); /* Receive data once sockfd is ready for reading */ FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((data_bytes = recvfrom(sockfd, data, MAX_DATA, 0, NULL, &len)) != 0); /* Audit record must contain sockfd and data_bytes */ snprintf(extregex, sizeof(extregex), "recvfrom.*0x%x.*return,success,%zd", sockfd, data_bytes); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(2, sockfd, sockfd2); } ATF_TC_CLEANUP(recvfrom_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(recvfrom_failure); ATF_TC_HEAD(recvfrom_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "recvfrom(2) call"); } ATF_TC_BODY(recvfrom_failure, tc) { snprintf(extregex, sizeof(extregex), "recvfrom.*%s", invalregex); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, recvfrom(-1, NULL, 0, 0, NULL, NULL)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(recvfrom_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(sendmsg_success); ATF_TC_HEAD(sendmsg_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "recvmsg(2) call"); } ATF_TC_BODY(sendmsg_success, tc) { assign_address(&server); /* Create a datagram server socket & bind to UNIX address family */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); /* Message buffer to be sent to the server */ init_iov(&io1, msgbuff, sizeof(msgbuff)); init_msghdr(&sendbuf, &io1, &server); /* Set up UDP client to communicate with the server */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); /* Send a sample message to the specified client address */ FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((data_bytes = sendmsg(sockfd2, &sendbuf, 0)) != -1); /* Audit record must contain sockfd2 and data_bytes */ snprintf(extregex, sizeof(extregex), "sendmsg.*0x%x.*return,success,%zd", sockfd2, data_bytes); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(2, sockfd, sockfd2); } ATF_TC_CLEANUP(sendmsg_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(sendmsg_failure); ATF_TC_HEAD(sendmsg_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "sendmsg(2) call"); } ATF_TC_BODY(sendmsg_failure, tc) { snprintf(extregex, sizeof(extregex), "sendmsg.*return,failure : Bad address"); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, sendmsg(-1, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(sendmsg_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(recvmsg_success); ATF_TC_HEAD(recvmsg_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "recvmsg(2) call"); } ATF_TC_BODY(recvmsg_success, tc) { assign_address(&server); /* Create a datagram server socket & bind to UNIX address family */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); /* Message buffer to be sent to the server */ init_iov(&io1, msgbuff, sizeof(msgbuff)); init_msghdr(&sendbuf, &io1, &server); /* Prepare buffer to store the received data in */ init_iov(&io2, data, sizeof(data)); init_msghdr(&recvbuf, &io2, NULL); /* Set up UDP client to communicate with the server */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); /* Send a sample message to the connected socket */ ATF_REQUIRE(sendmsg(sockfd2, &sendbuf, 0) != -1); /* Receive data once clientfd is ready for reading */ FILE *pipefd = setup(fds, auclass); ATF_REQUIRE((data_bytes = recvmsg(sockfd, &recvbuf, 0)) != -1); /* Audit record must contain sockfd and data_bytes */ snprintf(extregex, sizeof(extregex), "recvmsg.*%#x.*return,success,%zd", sockfd, data_bytes); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(2, sockfd, sockfd2); } ATF_TC_CLEANUP(recvmsg_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(recvmsg_failure); ATF_TC_HEAD(recvmsg_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "recvmsg(2) call"); } ATF_TC_BODY(recvmsg_failure, tc) { snprintf(extregex, sizeof(extregex), "recvmsg.*return,failure : Bad address"); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, recvmsg(-1, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(recvmsg_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(shutdown_success); ATF_TC_HEAD(shutdown_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "shutdown(2) call"); } ATF_TC_BODY(shutdown_success, tc) { assign_address(&server); /* Setup server socket and bind to the specified address */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); ATF_REQUIRE_EQ(0, listen(sockfd, 1)); /* Setup client and connect with the blocking server */ ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); /* Audit record must contain clientfd */ snprintf(extregex, sizeof(extregex), "shutdown.*%#x.*return,success", connectfd); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, shutdown(connectfd, SHUT_RDWR)); check_audit(fds, extregex, pipefd); /* Close all socket descriptors */ close_sockets(3, sockfd, sockfd2, connectfd); } ATF_TC_CLEANUP(shutdown_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(shutdown_failure); ATF_TC_HEAD(shutdown_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "shutdown(2) call"); } ATF_TC_BODY(shutdown_failure, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "shutdown.*%d.*return,failure", pid); FILE *pipefd = setup(fds, auclass); /* Failure reason: Invalid socket descriptor */ ATF_REQUIRE_EQ(-1, shutdown(-1, SHUT_RDWR)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(shutdown_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(sendfile_success); ATF_TC_HEAD(sendfile_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "sendfile(2) call"); } ATF_TC_BODY(sendfile_success, tc) { int filedesc; ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDONLY, mode)) != -1); /* Create a simple UNIX socket to send out random data */ ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); /* Check the presence of sockfd, non-file in the audit record */ snprintf(extregex, sizeof(extregex), "sendfile.*%#x,non-file.*return,success", filedesc); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, sendfile(filedesc, sockfd, 0, 0, NULL, NULL, 0)); check_audit(fds, extregex, pipefd); /* Teardown socket and file descriptors */ close_sockets(2, sockfd, filedesc); } ATF_TC_CLEANUP(sendfile_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(sendfile_failure); ATF_TC_HEAD(sendfile_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "sendfile(2) call"); } ATF_TC_BODY(sendfile_failure, tc) { pid = getpid(); snprintf(extregex, sizeof(extregex), "sendfile.*%d.*return,failure", pid); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, sendfile(-1, -1, 0, 0, NULL, NULL, 0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(sendfile_failure, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(setfib_success); ATF_TC_HEAD(setfib_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " "setfib(2) call"); } ATF_TC_BODY(setfib_success, tc) { - /* BSM conversion requested for unknown event 43228 */ - atf_tc_expect_fail("PR 228374: setfib(2) does not get audited in success mode"); - pid = getpid(); snprintf(extregex, sizeof(extregex), "setfib.*%d.*return,success", pid); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, setfib(0)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(setfib_success, tc) { cleanup(); } ATF_TC_WITH_CLEANUP(setfib_failure); ATF_TC_HEAD(setfib_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " "setfib(2) call"); } ATF_TC_BODY(setfib_failure, tc) { - /* BSM conversion requested for unknown event 43228 */ - atf_tc_expect_fail("PR 228374: setfib(2) does not get audited in failure mode"); - pid = getpid(); snprintf(extregex, sizeof(extregex), "setfib.*%d.*return,failure", pid); FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, setfib(-1)); check_audit(fds, extregex, pipefd); } ATF_TC_CLEANUP(setfib_failure, tc) { cleanup(); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, socket_success); ATF_TP_ADD_TC(tp, socket_failure); ATF_TP_ADD_TC(tp, socketpair_success); ATF_TP_ADD_TC(tp, socketpair_failure); ATF_TP_ADD_TC(tp, setsockopt_success); ATF_TP_ADD_TC(tp, setsockopt_failure); ATF_TP_ADD_TC(tp, bind_success); ATF_TP_ADD_TC(tp, bind_failure); ATF_TP_ADD_TC(tp, bindat_success); ATF_TP_ADD_TC(tp, bindat_failure); ATF_TP_ADD_TC(tp, listen_success); ATF_TP_ADD_TC(tp, listen_failure); ATF_TP_ADD_TC(tp, connect_success); ATF_TP_ADD_TC(tp, connect_failure); ATF_TP_ADD_TC(tp, connectat_success); ATF_TP_ADD_TC(tp, connectat_failure); ATF_TP_ADD_TC(tp, accept_success); ATF_TP_ADD_TC(tp, accept_failure); ATF_TP_ADD_TC(tp, send_success); ATF_TP_ADD_TC(tp, send_failure); ATF_TP_ADD_TC(tp, recv_success); ATF_TP_ADD_TC(tp, recv_failure); ATF_TP_ADD_TC(tp, sendto_success); ATF_TP_ADD_TC(tp, sendto_failure); ATF_TP_ADD_TC(tp, recvfrom_success); ATF_TP_ADD_TC(tp, recvfrom_failure); ATF_TP_ADD_TC(tp, sendmsg_success); ATF_TP_ADD_TC(tp, sendmsg_failure); ATF_TP_ADD_TC(tp, recvmsg_success); ATF_TP_ADD_TC(tp, recvmsg_failure); ATF_TP_ADD_TC(tp, shutdown_success); ATF_TP_ADD_TC(tp, shutdown_failure); ATF_TP_ADD_TC(tp, sendfile_success); ATF_TP_ADD_TC(tp, sendfile_failure); ATF_TP_ADD_TC(tp, setfib_success); ATF_TP_ADD_TC(tp, setfib_failure); return (atf_no_error()); }