X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/008676633c2ad2c325837c2b64915f7ded690a8f..c3c9b80d004dbbfdf763edeb97968c6997e3b45b:/bsd/security/audit/audit_arg.c diff --git a/bsd/security/audit/audit_arg.c b/bsd/security/audit/audit_arg.c index 7e338fd2b..c4ed65792 100644 --- a/bsd/security/audit/audit_arg.c +++ b/bsd/security/audit/audit_arg.c @@ -59,6 +59,8 @@ #include #include #include +#include +#include #include #include @@ -73,7 +75,6 @@ #include #include -#include #include #include @@ -111,16 +112,16 @@ audit_arg_addr(struct kaudit_record *ar, user_addr_t addr) /* * If the process is 64-bit then flag the address as such. */ - if (proc_is64bit(p)) + if (proc_is64bit(p)) { ARG_SET_VALID(ar, ARG_ADDR64); - else + } else { ARG_SET_VALID(ar, ARG_ADDR32); + } } void audit_arg_exit(struct kaudit_record *ar, int status, int retval) { - ar->k_ar.ar_arg_exitstatus = status; ar->k_ar.ar_arg_exitretval = retval; ARG_SET_VALID(ar, ARG_EXIT); @@ -129,7 +130,6 @@ audit_arg_exit(struct kaudit_record *ar, int status, int retval) void audit_arg_len(struct kaudit_record *ar, user_size_t len) { - ar->k_ar.ar_arg_len = len; ARG_SET_VALID(ar, ARG_LEN); } @@ -137,7 +137,6 @@ audit_arg_len(struct kaudit_record *ar, user_size_t len) void audit_arg_fd2(struct kaudit_record *ar, int fd) { - ar->k_ar.ar_arg_fd2 = fd; ARG_SET_VALID(ar, ARG_FD2); } @@ -145,7 +144,6 @@ audit_arg_fd2(struct kaudit_record *ar, int fd) void audit_arg_fd(struct kaudit_record *ar, int fd) { - ar->k_ar.ar_arg_fd = fd; ARG_SET_VALID(ar, ARG_FD); } @@ -153,7 +151,6 @@ audit_arg_fd(struct kaudit_record *ar, int fd) void audit_arg_fflags(struct kaudit_record *ar, int fflags) { - ar->k_ar.ar_arg_fflags = fflags; ARG_SET_VALID(ar, ARG_FFLAGS); } @@ -161,7 +158,6 @@ audit_arg_fflags(struct kaudit_record *ar, int fflags) void audit_arg_gid(struct kaudit_record *ar, gid_t gid) { - ar->k_ar.ar_arg_gid = gid; ARG_SET_VALID(ar, ARG_GID); } @@ -169,7 +165,6 @@ audit_arg_gid(struct kaudit_record *ar, gid_t gid) void audit_arg_uid(struct kaudit_record *ar, uid_t uid) { - ar->k_ar.ar_arg_uid = uid; ARG_SET_VALID(ar, ARG_UID); } @@ -177,7 +172,6 @@ audit_arg_uid(struct kaudit_record *ar, uid_t uid) void audit_arg_egid(struct kaudit_record *ar, gid_t egid) { - ar->k_ar.ar_arg_egid = egid; ARG_SET_VALID(ar, ARG_EGID); } @@ -185,7 +179,6 @@ audit_arg_egid(struct kaudit_record *ar, gid_t egid) void audit_arg_euid(struct kaudit_record *ar, uid_t euid) { - ar->k_ar.ar_arg_euid = euid; ARG_SET_VALID(ar, ARG_EUID); } @@ -193,7 +186,6 @@ audit_arg_euid(struct kaudit_record *ar, uid_t euid) void audit_arg_rgid(struct kaudit_record *ar, gid_t rgid) { - ar->k_ar.ar_arg_rgid = rgid; ARG_SET_VALID(ar, ARG_RGID); } @@ -201,7 +193,6 @@ audit_arg_rgid(struct kaudit_record *ar, gid_t rgid) void audit_arg_ruid(struct kaudit_record *ar, uid_t ruid) { - ar->k_ar.ar_arg_ruid = ruid; ARG_SET_VALID(ar, ARG_RUID); } @@ -209,7 +200,6 @@ audit_arg_ruid(struct kaudit_record *ar, uid_t ruid) void audit_arg_sgid(struct kaudit_record *ar, gid_t sgid) { - ar->k_ar.ar_arg_sgid = sgid; ARG_SET_VALID(ar, ARG_SGID); } @@ -217,7 +207,6 @@ audit_arg_sgid(struct kaudit_record *ar, gid_t sgid) void audit_arg_suid(struct kaudit_record *ar, uid_t suid) { - ar->k_ar.ar_arg_suid = suid; ARG_SET_VALID(ar, ARG_SUID); } @@ -227,8 +216,9 @@ audit_arg_groupset(struct kaudit_record *ar, gid_t *gidset, u_int gidset_size) { u_int i; - for (i = 0; i < gidset_size; i++) + for (i = 0; i < gidset_size; i++) { ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; + } ar->k_ar.ar_arg_groups.gidset_size = gidset_size; ARG_SET_VALID(ar, ARG_GROUPSET); } @@ -236,7 +226,6 @@ audit_arg_groupset(struct kaudit_record *ar, gid_t *gidset, u_int gidset_size) void audit_arg_login(struct kaudit_record *ar, char *login) { - strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); ARG_SET_VALID(ar, ARG_LOGIN); } @@ -244,7 +233,6 @@ audit_arg_login(struct kaudit_record *ar, char *login) void audit_arg_ctlname(struct kaudit_record *ar, int *name, int namelen) { - bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); ar->k_ar.ar_arg_len = namelen; ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); @@ -253,7 +241,6 @@ audit_arg_ctlname(struct kaudit_record *ar, int *name, int namelen) void audit_arg_mask(struct kaudit_record *ar, int mask) { - ar->k_ar.ar_arg_mask = mask; ARG_SET_VALID(ar, ARG_MASK); } @@ -261,7 +248,6 @@ audit_arg_mask(struct kaudit_record *ar, int mask) void audit_arg_mode(struct kaudit_record *ar, mode_t mode) { - ar->k_ar.ar_arg_mode = mode; ARG_SET_VALID(ar, ARG_MODE); } @@ -269,7 +255,6 @@ audit_arg_mode(struct kaudit_record *ar, mode_t mode) void audit_arg_value32(struct kaudit_record *ar, uint32_t value32) { - ar->k_ar.ar_arg_value32 = value32; ARG_SET_VALID(ar, ARG_VALUE32); } @@ -277,7 +262,6 @@ audit_arg_value32(struct kaudit_record *ar, uint32_t value32) void audit_arg_value64(struct kaudit_record *ar, uint64_t value64) { - ar->k_ar.ar_arg_value64 = value64; ARG_SET_VALID(ar, ARG_VALUE64); } @@ -285,7 +269,6 @@ audit_arg_value64(struct kaudit_record *ar, uint64_t value64) void audit_arg_owner(struct kaudit_record *ar, uid_t uid, gid_t gid) { - ar->k_ar.ar_arg_uid = uid; ar->k_ar.ar_arg_gid = gid; ARG_SET_VALID(ar, ARG_UID | ARG_GID); @@ -294,7 +277,6 @@ audit_arg_owner(struct kaudit_record *ar, uid_t uid, gid_t gid) void audit_arg_pid(struct kaudit_record *ar, pid_t pid) { - ar->k_ar.ar_arg_pid = pid; ARG_SET_VALID(ar, ARG_PID); } @@ -306,8 +288,9 @@ audit_arg_process(struct kaudit_record *ar, proc_t p) KASSERT(p != NULL, ("audit_arg_process: p == NULL")); - if ( p == NULL) + if (p == NULL) { return; + } my_cred = kauth_cred_proc_ref(p); ar->k_ar.ar_arg_auid = my_cred->cr_audit.as_aia_p->ai_auid; @@ -327,7 +310,6 @@ audit_arg_process(struct kaudit_record *ar, proc_t p) void audit_arg_signum(struct kaudit_record *ar, u_int signum) { - ar->k_ar.ar_arg_signum = signum; ARG_SET_VALID(ar, ARG_SIGNUM); } @@ -336,7 +318,6 @@ void audit_arg_socket(struct kaudit_record *ar, int sodomain, int sotype, int soprotocol) { - ar->k_ar.ar_arg_sockinfo.sai_domain = sodomain; ar->k_ar.ar_arg_sockinfo.sai_type = sotype; ar->k_ar.ar_arg_sockinfo.sai_protocol = soprotocol; @@ -360,13 +341,15 @@ audit_arg_sockaddr(struct kaudit_record *ar, struct vnode *cwd_vp, KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); - if (cwd_vp == NULL || sa == NULL) + if (cwd_vp == NULL || sa == NULL) { return; + } - if (sa->sa_len > sizeof(ar->k_ar.ar_arg_sockaddr)) + if (sa->sa_len > sizeof(ar->k_ar.ar_arg_sockaddr)) { bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sizeof(ar->k_ar.ar_arg_sockaddr)); - else + } else { bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); + } switch (sa->sa_family) { case AF_INET: @@ -390,14 +373,13 @@ audit_arg_sockaddr(struct kaudit_record *ar, struct vnode *cwd_vp, } ARG_SET_VALID(ar, ARG_SADDRUNIX); break; - /* XXXAUDIT: default:? */ + /* XXXAUDIT: default:? */ } } void audit_arg_auid(struct kaudit_record *ar, uid_t auid) { - ar->k_ar.ar_arg_auid = auid; ARG_SET_VALID(ar, ARG_AUID); } @@ -405,7 +387,6 @@ audit_arg_auid(struct kaudit_record *ar, uid_t auid) void audit_arg_auditinfo(struct kaudit_record *ar, struct auditinfo *au_info) { - ar->k_ar.ar_arg_auid = au_info->ai_auid; ar->k_ar.ar_arg_asid = au_info->ai_asid; ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; @@ -419,7 +400,6 @@ void audit_arg_auditinfo_addr(struct kaudit_record *ar, struct auditinfo_addr *au_info) { - ar->k_ar.ar_arg_auid = au_info->ai_auid; ar->k_ar.ar_arg_asid = au_info->ai_asid; ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; @@ -436,36 +416,38 @@ audit_arg_auditinfo_addr(struct kaudit_record *ar, void audit_arg_text(struct kaudit_record *ar, char *text) { - KASSERT(text != NULL, ("audit_arg_text: text == NULL")); /* Invalidate the text string */ ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); - if (text == NULL) + if (text == NULL) { return; + } - if (ar->k_ar.ar_arg_text == NULL) - ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, + if (ar->k_ar.ar_arg_text == NULL) { + ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, M_WAITOK); + } - strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); + strlcpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); ARG_SET_VALID(ar, ARG_TEXT); } void audit_arg_opaque(struct kaudit_record *ar, void *data, size_t size) { - KASSERT(data != NULL, ("audit_arg_opaque: data == NULL")); KASSERT(size <= UINT16_MAX, ("audit_arg_opaque: size > UINT16_MAX")); - if (data == NULL || size > UINT16_MAX) + if (data == NULL || size > UINT16_MAX) { return; + } - if (ar->k_ar.ar_arg_opaque == NULL) + if (ar->k_ar.ar_arg_opaque == NULL) { ar->k_ar.ar_arg_opaque = malloc(size, M_AUDITDATA, M_WAITOK); - else + } else { return; + } memcpy(ar->k_ar.ar_arg_opaque, data, size); ar->k_ar.ar_arg_opq_size = (u_int16_t) size; @@ -484,19 +466,21 @@ audit_arg_data(struct kaudit_record *ar, void *data, size_t size, size_t number) ("audit_arg_data: number > UINT8_MAX")); if (data == NULL || size < AUR_BYTE_SIZE || size > AUR_INT64_SIZE || - number > UINT8_MAX) + number > UINT8_MAX) { return; + } sz = size * number; - if (ar->k_ar.ar_arg_data == NULL) + if (ar->k_ar.ar_arg_data == NULL) { ar->k_ar.ar_arg_data = malloc(sz, M_AUDITDATA, M_WAITOK); - else + } else { return; + } memcpy(ar->k_ar.ar_arg_data, data, sz); - switch(size) { + switch (size) { case AUR_BYTE_SIZE: ar->k_ar.ar_arg_data_type = AUR_BYTE; break; @@ -527,7 +511,6 @@ audit_arg_data(struct kaudit_record *ar, void *data, size_t size, size_t number) void audit_arg_cmd(struct kaudit_record *ar, int cmd) { - ar->k_ar.ar_arg_cmd = cmd; ARG_SET_VALID(ar, ARG_CMD); } @@ -535,7 +518,6 @@ audit_arg_cmd(struct kaudit_record *ar, int cmd) void audit_arg_svipc_cmd(struct kaudit_record *ar, int cmd) { - ar->k_ar.ar_arg_svipc_cmd = cmd; ARG_SET_VALID(ar, ARG_SVIPC_CMD); } @@ -543,7 +525,6 @@ audit_arg_svipc_cmd(struct kaudit_record *ar, int cmd) void audit_arg_svipc_perm(struct kaudit_record *ar, struct ipc_perm *perm) { - bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, sizeof(ar->k_ar.ar_arg_svipc_perm)); ARG_SET_VALID(ar, ARG_SVIPC_PERM); @@ -552,7 +533,6 @@ audit_arg_svipc_perm(struct kaudit_record *ar, struct ipc_perm *perm) void audit_arg_svipc_id(struct kaudit_record *ar, int id) { - ar->k_ar.ar_arg_svipc_id = id; ARG_SET_VALID(ar, ARG_SVIPC_ID); } @@ -560,7 +540,6 @@ audit_arg_svipc_id(struct kaudit_record *ar, int id) void audit_arg_svipc_addr(struct kaudit_record *ar, user_addr_t addr) { - ar->k_ar.ar_arg_svipc_addr = addr; ARG_SET_VALID(ar, ARG_SVIPC_ADDR); } @@ -569,7 +548,6 @@ void audit_arg_posix_ipc_perm(struct kaudit_record *ar, uid_t uid, gid_t gid, mode_t mode) { - ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; @@ -579,7 +557,6 @@ audit_arg_posix_ipc_perm(struct kaudit_record *ar, uid_t uid, gid_t gid, void audit_arg_auditon(struct kaudit_record *ar, union auditon_udata *udata) { - bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, sizeof(ar->k_ar.ar_arg_auditon)); ARG_SET_VALID(ar, ARG_AUDITON); @@ -598,18 +575,19 @@ audit_arg_file(struct kaudit_record *ar, __unused proc_t p, struct sockaddr_in *sin; struct sockaddr_in6 *sin6; - switch (FILEGLOB_DTYPE(fp->f_fglob)) { + switch (FILEGLOB_DTYPE(fp->fp_glob)) { case DTYPE_VNODE: - /* case DTYPE_FIFO: */ + /* case DTYPE_FIFO: */ audit_arg_vnpath_withref(ar, - (struct vnode *)fp->f_fglob->fg_data, ARG_VNODE1); + (struct vnode *)fp->fp_glob->fg_data, ARG_VNODE1); break; case DTYPE_SOCKET: - so = (struct socket *)fp->f_fglob->fg_data; + so = (struct socket *)fp->fp_glob->fg_data; if (SOCK_CHECK_DOM(so, PF_INET)) { - if (so->so_pcb == NULL) + if (so->so_pcb == NULL) { break; + } ar->k_ar.ar_arg_sockinfo.sai_type = so->so_type; ar->k_ar.ar_arg_sockinfo.sai_domain = SOCK_DOM(so); @@ -626,8 +604,9 @@ audit_arg_file(struct kaudit_record *ar, __unused proc_t p, ARG_SET_VALID(ar, ARG_SOCKINFO); } if (SOCK_CHECK_DOM(so, PF_INET6)) { - if (so->so_pcb == NULL) + if (so->so_pcb == NULL) { break; + } ar->k_ar.ar_arg_sockinfo.sai_type = so->so_type; ar->k_ar.ar_arg_sockinfo.sai_domain = SOCK_DOM(so); @@ -656,7 +635,7 @@ audit_arg_file(struct kaudit_record *ar, __unused proc_t p, * record stored on the user thread. This function will allocate the memory * to store the path info if not already available. This memory will be * freed when the audit record is freed. - * + * * Note that the current working directory vp must be supplied at the audit call * site to permit per thread current working directories, and that it must take * a upath starting with '/' into account for chroot if the path is absolute. @@ -676,24 +655,53 @@ audit_arg_upath(struct kaudit_record *ar, struct vnode *cwd_vp, char *upath, u_i KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2), ("audit_arg_upath: flag %llu", (unsigned long long)flag)); - if (flag == ARG_UPATH1) + if (flag == ARG_UPATH1) { pathp = &ar->k_ar.ar_arg_upath1; - else + } else { pathp = &ar->k_ar.ar_arg_upath2; + } - if (*pathp == NULL) + if (*pathp == NULL) { *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); - else + } else { return; + } - if (audit_canon_path(cwd_vp, upath, *pathp) == 0) + if (audit_canon_path(cwd_vp, upath, *pathp) == 0) { ARG_SET_VALID(ar, flag); - else { + } else { free(*pathp, M_AUDITPATH); *pathp = NULL; } } +void +audit_arg_kpath(struct kaudit_record *ar, char *kpath, u_int64_t flag) +{ + char **pathp; + + KASSERT(kpath != NULL, ("audit_arg_kpath: kpath == NULL")); + KASSERT((flag == ARG_KPATH1) || (flag == ARG_KPATH2), + ("audit_arg_kpath: flag %llu", (unsigned long long)flag)); + KASSERT((flag != ARG_KPATH1) || (flag != ARG_KPATH2), + ("audit_arg_kpath: flag %llu", (unsigned long long)flag)); + + if (flag == ARG_KPATH1) { + pathp = &ar->k_ar.ar_arg_kpath1; + } else { + pathp = &ar->k_ar.ar_arg_kpath2; + } + + if (*pathp == NULL) { + *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); + } else { + return; + } + + strlcpy(*pathp, kpath, MAXPATHLEN); + ARG_SET_VALID(ar, flag); +} + /* * Function to save the path and vnode attr information into the audit * record. @@ -732,7 +740,7 @@ audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) p = current_proc(); - /* + /* * XXXAUDIT: The below clears, and then resets the flags for valid * arguments. Ideally, either the new vnode is used, or the old one * would be. @@ -755,10 +763,11 @@ audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) #endif } - if (*pathp == NULL) + if (*pathp == NULL) { *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); - else + } else { return; + } /* * If vn_getpath() succeeds, place it in a string buffer @@ -767,10 +776,11 @@ audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) */ len = MAXPATHLEN; if (vn_getpath(vp, *pathp, &len) == 0) { - if (flags & ARG_VNODE1) + if (flags & ARG_VNODE1) { ARG_SET_VALID(ar, ARG_KPATH1); - else + } else { ARG_SET_VALID(ar, ARG_KPATH2); + } } else { free(*pathp, M_AUDITPATH); *pathp = NULL; @@ -796,7 +806,9 @@ audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) if (*vnode_mac_labelp != NULL) { mac.m_buflen = MAC_AUDIT_LABEL_LEN; mac.m_string = *vnode_mac_labelp; - mac_vnode_label_externalize_audit(vp, &mac); + if (mac_vnode_label_externalize_audit(vp, &mac)) { + return; + } } } #endif @@ -811,17 +823,19 @@ audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) vnp->vn_fsid = va.va_fsid; vnp->vn_fileid = (u_int32_t)va.va_fileid; vnp->vn_gen = va.va_gen; - if (flags & ARG_VNODE1) + if (flags & ARG_VNODE1) { ARG_SET_VALID(ar, ARG_VNODE1); - else + } else { ARG_SET_VALID(ar, ARG_VNODE2); + } } void audit_arg_vnpath_withref(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) { - if (vp == NULL || vnode_getwithref(vp)) + if (vp == NULL || vnode_getwithref(vp)) { return; + } audit_arg_vnpath(ar, vp, flags); (void)vnode_put(vp); } @@ -829,7 +843,6 @@ audit_arg_vnpath_withref(struct kaudit_record *ar, struct vnode *vp, u_int64_t f void audit_arg_mach_port1(struct kaudit_record *ar, mach_port_name_t port) { - ar->k_ar.ar_arg_mach_port1 = port; ARG_SET_VALID(ar, ARG_MACHPORT1); } @@ -837,7 +850,6 @@ audit_arg_mach_port1(struct kaudit_record *ar, mach_port_name_t port) void audit_arg_mach_port2(struct kaudit_record *ar, mach_port_name_t port) { - ar->k_ar.ar_arg_mach_port2 = port; ARG_SET_VALID(ar, ARG_MACHPORT2); } @@ -847,14 +859,15 @@ audit_arg_mach_port2(struct kaudit_record *ar, mach_port_name_t port) * Audit the argument strings passed to exec. */ void -audit_arg_argv(struct kaudit_record *ar, char *argv, int argc, int length) +audit_arg_argv(struct kaudit_record *ar, char *argv, int argc, size_t length) { - - if (audit_argv == 0 || argc == 0) + if (audit_argv == 0 || argc == 0) { return; + } - if (ar->k_ar.ar_arg_argv == NULL) + if (ar->k_ar.ar_arg_argv == NULL) { ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); + } bcopy(argv, ar->k_ar.ar_arg_argv, length); ar->k_ar.ar_arg_argc = argc; ARG_SET_VALID(ar, ARG_ARGV); @@ -864,14 +877,15 @@ audit_arg_argv(struct kaudit_record *ar, char *argv, int argc, int length) * Audit the environment strings passed to exec. */ void -audit_arg_envv(struct kaudit_record *ar, char *envv, int envc, int length) +audit_arg_envv(struct kaudit_record *ar, char *envv, int envc, size_t length) { - - if (audit_arge == 0 || envc == 0) + if (audit_arge == 0 || envc == 0) { return; + } - if (ar->k_ar.ar_arg_envv == NULL) + if (ar->k_ar.ar_arg_envv == NULL) { ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); + } bcopy(envv, ar->k_ar.ar_arg_envv, length); ar->k_ar.ar_arg_envc = envc; ARG_SET_VALID(ar, ARG_ENVV); @@ -892,12 +906,100 @@ audit_sysclose(struct kaudit_record *ar, proc_t p, int fd) audit_arg_fd(ar, fd); - if (fp_getfvp(p, fd, &fp, &vp) != 0) + if (fp_getfvp(p, fd, &fp, &vp) != 0) { return; + } - audit_arg_vnpath_withref(ar, (struct vnode *)fp->f_fglob->fg_data, + audit_arg_vnpath_withref(ar, (struct vnode *)fp->fp_glob->fg_data, ARG_VNODE1); fp_drop(p, fd, fp, 0); } +void +audit_identity_info_destruct(struct au_identity_info *id_info) +{ + if (!id_info) { + return; + } + + if (id_info->signing_id != NULL) { + free(id_info->signing_id, M_AUDITTEXT); + id_info->signing_id = NULL; + } + + if (id_info->team_id != NULL) { + free(id_info->team_id, M_AUDITTEXT); + id_info->team_id = NULL; + } + + if (id_info->cdhash != NULL) { + free(id_info->cdhash, M_AUDITDATA); + id_info->cdhash = NULL; + } +} + +void +audit_identity_info_construct(struct au_identity_info *id_info) +{ + struct proc *p; + struct cs_blob *blob; + unsigned int signer_type = 0; + const char *signing_id = NULL; + const char* team_id = NULL; + const uint8_t *cdhash = NULL; + size_t src_len = 0; + + p = current_proc(); + blob = csproc_get_blob(p); + if (blob) { + signing_id = csblob_get_identity(blob); + cdhash = csblob_get_cdhash(blob); + team_id = csblob_get_teamid(blob); + signer_type = csblob_get_platform_binary(blob) ? 1 : 0; + } + + id_info->signer_type = signer_type; + + if (id_info->signing_id == NULL && signing_id != NULL) { + id_info->signing_id = malloc( MAX_AU_IDENTITY_SIGNING_ID_LENGTH, + M_AUDITTEXT, M_WAITOK); + if (id_info->signing_id != NULL) { + src_len = strlcpy(id_info->signing_id, + signing_id, MAX_AU_IDENTITY_SIGNING_ID_LENGTH); + + if (src_len >= MAX_AU_IDENTITY_SIGNING_ID_LENGTH) { + id_info->signing_id_trunc = 1; + } + } + } + + if (id_info->team_id == NULL && team_id != NULL) { + id_info->team_id = malloc(MAX_AU_IDENTITY_TEAM_ID_LENGTH, + M_AUDITTEXT, M_WAITOK); + if (id_info->team_id != NULL) { + src_len = strlcpy(id_info->team_id, team_id, + MAX_AU_IDENTITY_TEAM_ID_LENGTH); + + if (src_len >= MAX_AU_IDENTITY_TEAM_ID_LENGTH) { + id_info->team_id_trunc = 1; + } + } + } + + if (id_info->cdhash == NULL && cdhash != NULL) { + id_info->cdhash = malloc(CS_CDHASH_LEN, M_AUDITDATA, M_WAITOK); + if (id_info->cdhash != NULL) { + memcpy(id_info->cdhash, cdhash, CS_CDHASH_LEN); + id_info->cdhash_len = CS_CDHASH_LEN; + } + } +} + +void +audit_arg_identity(struct kaudit_record *ar) +{ + audit_identity_info_construct(&ar->k_ar.ar_arg_identity); + ARG_SET_VALID(ar, ARG_IDENTITY); +} + #endif /* CONFIG_AUDIT */