X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..b226f5e54a60dc81db17b1260381d7dbfea3cdf1:/bsd/security/audit/audit_bsm.c diff --git a/bsd/security/audit/audit_bsm.c b/bsd/security/audit/audit_bsm.c index 7ca2771d4..876833e4b 100644 --- a/bsd/security/audit/audit_bsm.c +++ b/bsd/security/audit/audit_bsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2009 Apple Inc. + * Copyright (c) 1999-2016 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -227,6 +227,13 @@ kau_free(struct au_record *rec) } \ } while (0) +#define KPATH2_TOKENS do { \ + if (ARG_IS_VALID(kar, ARG_KPATH2)) { \ + tok = au_to_path(ar->ar_arg_kpath2); \ + kau_write(rec, tok); \ + } \ +} while (0) + #define VNODE1_TOKENS do { \ if (ARG_IS_VALID(kar, ARG_KPATH1)) { \ tok = au_to_path(ar->ar_arg_kpath1); \ @@ -263,6 +270,18 @@ kau_free(struct au_record *rec) } \ } while (0) +#define VNODE2_PATH_TOKENS do { \ + if (ARG_IS_VALID(kar, ARG_KPATH2)) { \ + tok = au_to_path(ar->ar_arg_kpath2); \ + kau_write(rec, tok); \ + } \ + if (ARG_IS_VALID(kar, ARG_VNODE2)) { \ + tok = au_to_attr32(&ar->ar_arg_vnode2); \ + kau_write(rec, tok); \ + MAC_VNODE2_LABEL_TOKEN; \ + } \ +} while (0) + #define FD_VNODE1_TOKENS do { \ if (ARG_IS_VALID(kar, ARG_VNODE1)) { \ if (ARG_IS_VALID(kar, ARG_KPATH1)) { \ @@ -983,6 +1002,12 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) kau_write(rec, tok); } UPATH1_VNODE1_TOKENS; + VNODE2_PATH_TOKENS; + if (ARG_IS_VALID(kar, ARG_DATA)) { + tok = au_to_data(AUP_HEX, ar->ar_arg_data_type, + ar->ar_arg_data_count, ar->ar_arg_data); + kau_write(rec, tok); + } break; case AUE_FCHMOD_EXTENDED: @@ -1170,6 +1195,7 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) case AUE_RENAME: UPATH1_VNODE1_TOKENS; UPATH2_TOKENS; + KPATH2_TOKENS; break; case AUE_MKDIR_EXTENDED: @@ -1256,6 +1282,20 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) case AUE_UNMOUNT: UPATH1_VNODE1_TOKENS; break; + case AUE_FMOUNT: + if (ARG_IS_VALID(kar, ARG_FD)) { + tok = au_to_arg32(2, "dir fd", ar->ar_arg_fd); + kau_write(rec, tok); + } + 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); + } + break; case AUE_MSGCTL: ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd); @@ -1412,6 +1452,7 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) case AUE_SYMLINKAT: case AUE_MKDIRAT: case AUE_GETATTRLISTAT: + case AUE_SETATTRLISTAT: if (ARG_IS_VALID(kar, ARG_FD)) { tok = au_to_arg32(1, "dir fd", ar->ar_arg_fd); kau_write(rec, tok); @@ -1419,6 +1460,36 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) UPATH1_VNODE1_TOKENS; break; + case AUE_CLONEFILEAT: + if (ARG_IS_VALID(kar, ARG_FD)) { + tok = au_to_arg32(1, "src dir fd", ar->ar_arg_fd); + kau_write(rec, tok); + } + UPATH1_VNODE1_TOKENS; + if (ARG_IS_VALID(kar, ARG_FD2)) { + tok = au_to_arg32(1, "dst dir fd", ar->ar_arg_fd2); + kau_write(rec, tok); + } + UPATH2_TOKENS; + if (ARG_IS_VALID(kar, ARG_VALUE32)) { + tok = au_to_arg32(1, "flags", ar->ar_arg_value32); + kau_write(rec, tok); + } + break; + + case AUE_FCLONEFILEAT: + FD_VNODE1_TOKENS; + if (ARG_IS_VALID(kar, ARG_FD2)) { + tok = au_to_arg32(1, "dst dir fd", ar->ar_arg_fd2); + kau_write(rec, tok); + } + UPATH2_TOKENS; + if (ARG_IS_VALID(kar, ARG_VALUE32)) { + tok = au_to_arg32(1, "flags", ar->ar_arg_value32); + kau_write(rec, tok); + } + break; + case AUE_PTRACE: if (ARG_IS_VALID(kar, ARG_CMD)) { tok = au_to_arg32(1, "request", ar->ar_arg_cmd); @@ -1975,6 +2046,14 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval); kau_write(rec, tok); /* Every record gets a return token */ + if (ARG_IS_VALID(kar, ARG_IDENTITY)) { + struct au_identity_info *id = &ar->ar_arg_identity; + tok = au_to_identity(id->signer_type, id->signing_id, + id->signing_id_trunc, id->team_id, id->team_id_trunc, + id->cdhash, id->cdhash_len); + kau_write(rec, tok); + } + kau_close(rec, &ar->ar_endtime, ar->ar_event); *pau = rec; @@ -1982,25 +2061,47 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) } /* - * 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 + * Verify that a record is a valid BSM record. Return 1 if the * record is good, 0 otherwise. */ int -bsm_rec_verify(void *rec) +bsm_rec_verify(void *rec, int length) { - char c = *(char *)rec; + /* Used to partially deserialize the buffer */ + struct hdr_tok_partial *hdr; + struct trl_tok_partial *trl; - /* - * 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)) + /* A record requires a complete header and trailer token */ + if (length < (AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE)) { + return (0); + } + + hdr = (struct hdr_tok_partial*)rec; + + /* Ensure the provided length matches what the record shows */ + if ((uint32_t)length != ntohl(hdr->len)) { + return (0); + } + + trl = (struct trl_tok_partial*)(rec + (length - AUDIT_TRAILER_SIZE)); + + /* Ensure the buffer contains what look like header and trailer tokens */ + if (((hdr->type != AUT_HEADER32) && (hdr->type != AUT_HEADER32_EX) && + (hdr->type != AUT_HEADER64) && (hdr->type != AUT_HEADER64_EX)) || + (trl->type != AUT_TRAILER)) { return (0); + } + + /* Ensure the header and trailer agree on the length */ + if (hdr->len != trl->len) { + return (0); + } + + /* Ensure the trailer token has a proper magic value */ + if (ntohs(trl->magic) != AUT_TRAILER_MAGIC) { + return (0); + } + return (1); } #endif /* CONFIG_AUDIT */