* System call to allow a user space application to submit a BSM audit record * to the kernel for inclusion in the audit log. This function does little * verification on the audit record that is submitted. * * XXXAUDIT: Audit preselection for user records does not currently work, * since we pre-select only based on the AUE_audit event type, not the event * type submitted as part of the user
| 68 | */ |
| 69 | /* ARGSUSED */ |
| 70 | int |
| 71 | sys_audit(struct thread *td, struct audit_args *uap) |
| 72 | { |
| 73 | int error; |
| 74 | void * rec; |
| 75 | struct kaudit_record *ar; |
| 76 | |
| 77 | if (jailed(td->td_ucred)) |
| 78 | return (ENOSYS); |
| 79 | error = priv_check(td, PRIV_AUDIT_SUBMIT); |
| 80 | if (error) |
| 81 | return (error); |
| 82 | |
| 83 | if ((uap->length <= 0) || (uap->length > audit_qctrl.aq_bufsz)) |
| 84 | return (EINVAL); |
| 85 | |
| 86 | ar = currecord(); |
| 87 | |
| 88 | /* |
| 89 | * If there's no current audit record (audit() itself not audited) |
| 90 | * commit the user audit record. |
| 91 | */ |
| 92 | if (ar == NULL) { |
| 93 | /* |
| 94 | * This is not very efficient; we're required to allocate a |
| 95 | * complete kernel audit record just so the user record can |
| 96 | * tag along. |
| 97 | * |
| 98 | * XXXAUDIT: Maybe AUE_AUDIT in the system call context and |
| 99 | * special pre-select handling? |
| 100 | */ |
| 101 | td->td_ar = audit_new(AUE_NULL, td); |
| 102 | if (td->td_ar == NULL) |
| 103 | return (ENOTSUP); |
| 104 | td->td_pflags |= TDP_AUDITREC; |
| 105 | ar = td->td_ar; |
| 106 | } |
| 107 | |
| 108 | if (uap->length > MAX_AUDIT_RECORD_SIZE) |
| 109 | return (EINVAL); |
| 110 | |
| 111 | rec = malloc(uap->length, M_AUDITDATA, M_WAITOK); |
| 112 | |
| 113 | error = copyin(uap->record, rec, uap->length); |
| 114 | if (error) |
| 115 | goto free_out; |
| 116 | |
| 117 | /* Verify the record. */ |
| 118 | if (bsm_rec_verify(rec) == 0) { |
| 119 | error = EINVAL; |
| 120 | goto free_out; |
| 121 | } |
| 122 | |
| 123 | #ifdef MAC |
| 124 | error = mac_system_check_audit(td->td_ucred, rec, uap->length); |
| 125 | if (error) |
| 126 | goto free_out; |
| 127 | #endif |
nothing calls this directly
no test coverage detected