1 /* 2 * Copyright (c) 1999-2005 Apple Computer, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/namei.h> 34 #include <sys/proc.h> 35 #include <sys/sysproto.h> 36 #include <sys/systm.h> 37 #include <sys/vnode.h> 38 39 #include <bsm/audit.h> 40 #include <bsm/audit_kevents.h> 41 #include <security/audit/audit.h> 42 #include <security/audit/audit_private.h> 43 44 #ifdef AUDIT 45 46 /* 47 * MPSAFE 48 * 49 * System call to allow a user space application to submit a BSM audit record 50 * to the kernel for inclusion in the audit log. This function does little 51 * verification on the audit record that is submitted. 52 * 53 * XXXAUDIT: Audit preselection for user records does not currently work, 54 * since we pre-select only based on the AUE_audit event type, not the event 55 * type submitted as part of the user audit data. 56 */ 57 /* ARGSUSED */ 58 int 59 audit(struct thread *td, struct audit_args *uap) 60 { 61 int error; 62 void * rec; 63 struct kaudit_record *ar; 64 65 error = suser(td); 66 if (error) 67 return (error); 68 69 if ((uap->length <= 0) || (uap->length > audit_qctrl.aq_bufsz)) 70 return (EINVAL); 71 72 ar = currecord(); 73 74 /* 75 * If there's no current audit record (audit() itself not audited) 76 * commit the user audit record. 77 */ 78 if (ar == NULL) { 79 80 /* 81 * This is not very efficient; we're required to allocate a 82 * complete kernel audit record just so the user record can 83 * tag along. 84 * 85 * XXXAUDIT: Maybe AUE_AUDIT in the system call context and 86 * special pre-select handling? 87 */ 88 td->td_ar = audit_new(AUE_NULL, td); 89 if (td->td_ar == NULL) 90 return (ENOTSUP); 91 ar = td->td_ar; 92 } 93 94 if (uap->length > MAX_AUDIT_RECORD_SIZE) 95 return (EINVAL); 96 97 rec = malloc(uap->length, M_AUDITDATA, M_WAITOK); 98 99 error = copyin(uap->record, rec, uap->length); 100 if (error) 101 goto free_out; 102 103 /* Verify the record. */ 104 if (bsm_rec_verify(rec) == 0) { 105 error = EINVAL; 106 goto free_out; 107 } 108 109 /* 110 * Attach the user audit record to the kernel audit record. Because 111 * this system call is an auditable event, we will write the user 112 * record along with the record for this audit event. 113 * 114 * XXXAUDIT: KASSERT appropriate starting values of k_udata, k_ulen, 115 * k_ar_commit & AR_COMMIT_USER? 116 */ 117 ar->k_udata = rec; 118 ar->k_ulen = uap->length; 119 ar->k_ar_commit |= AR_COMMIT_USER; 120 return (0); 121 122 free_out: 123 /* 124 * audit_syscall_exit() will free the audit record on the thread even 125 * if we allocated it above. 126 */ 127 free(rec, M_AUDITDATA); 128 return (error); 129 } 130 131 /* 132 * MPSAFE 133 * 134 * System call to manipulate auditing. 135 */ 136 /* ARGSUSED */ 137 int 138 auditon(struct thread *td, struct auditon_args *uap) 139 { 140 int error; 141 union auditon_udata udata; 142 struct proc *tp; 143 144 AUDIT_ARG(cmd, uap->cmd); 145 error = suser(td); 146 if (error) 147 return (error); 148 149 if ((uap->length <= 0) || (uap->length > sizeof(union auditon_udata))) 150 return (EINVAL); 151 152 memset((void *)&udata, 0, sizeof(udata)); 153 154 /* 155 * Some of the GET commands use the arguments too. 156 */ 157 switch (uap->cmd) { 158 case A_SETPOLICY: 159 case A_SETKMASK: 160 case A_SETQCTRL: 161 case A_SETSTAT: 162 case A_SETUMASK: 163 case A_SETSMASK: 164 case A_SETCOND: 165 case A_SETCLASS: 166 case A_SETPMASK: 167 case A_SETFSIZE: 168 case A_SETKAUDIT: 169 case A_GETCLASS: 170 case A_GETPINFO: 171 case A_GETPINFO_ADDR: 172 case A_SENDTRIGGER: 173 error = copyin(uap->data, (void *)&udata, uap->length); 174 if (error) 175 return (error); 176 AUDIT_ARG(auditon, &udata); 177 break; 178 } 179 180 /* 181 * XXX Need to implement these commands by accessing the global 182 * values associated with the commands. 183 * 184 * XXXAUDIT: Locking? 185 */ 186 switch (uap->cmd) { 187 case A_GETPOLICY: 188 if (!audit_fail_stop) 189 udata.au_policy |= AUDIT_CNT; 190 if (audit_panic_on_write_fail) 191 udata.au_policy |= AUDIT_AHLT; 192 break; 193 194 case A_SETPOLICY: 195 if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT)) 196 return (EINVAL); 197 /* 198 * XXX - Need to wake up waiters if the policy relaxes? 199 */ 200 audit_fail_stop = ((udata.au_policy & AUDIT_CNT) == 0); 201 audit_panic_on_write_fail = (udata.au_policy & AUDIT_AHLT); 202 break; 203 204 case A_GETKMASK: 205 udata.au_mask = audit_nae_mask; 206 break; 207 208 case A_SETKMASK: 209 audit_nae_mask = udata.au_mask; 210 break; 211 212 case A_GETQCTRL: 213 udata.au_qctrl = audit_qctrl; 214 break; 215 216 case A_SETQCTRL: 217 if ((udata.au_qctrl.aq_hiwater > AQ_MAXHIGH) || 218 (udata.au_qctrl.aq_lowater >= udata.au_qctrl.aq_hiwater) || 219 (udata.au_qctrl.aq_bufsz > AQ_MAXBUFSZ) || 220 (udata.au_qctrl.aq_minfree < 0) || 221 (udata.au_qctrl.aq_minfree > 100)) 222 return (EINVAL); 223 224 audit_qctrl = udata.au_qctrl; 225 /* XXX The queue delay value isn't used with the kernel. */ 226 audit_qctrl.aq_delay = -1; 227 break; 228 229 case A_GETCWD: 230 return (ENOSYS); 231 break; 232 233 case A_GETCAR: 234 return (ENOSYS); 235 break; 236 237 case A_GETSTAT: 238 return (ENOSYS); 239 break; 240 241 case A_SETSTAT: 242 return (ENOSYS); 243 break; 244 245 case A_SETUMASK: 246 return (ENOSYS); 247 break; 248 249 case A_SETSMASK: 250 return (ENOSYS); 251 break; 252 253 case A_GETCOND: 254 if (audit_enabled && !audit_suspended) 255 udata.au_cond = AUC_AUDITING; 256 else 257 udata.au_cond = AUC_NOAUDIT; 258 break; 259 260 case A_SETCOND: 261 if (udata.au_cond == AUC_NOAUDIT) 262 audit_suspended = 1; 263 if (udata.au_cond == AUC_AUDITING) 264 audit_suspended = 0; 265 if (udata.au_cond == AUC_DISABLED) { 266 audit_suspended = 1; 267 audit_shutdown(NULL, 0); 268 } 269 break; 270 271 case A_GETCLASS: 272 udata.au_evclass.ec_class = au_event_class( 273 udata.au_evclass.ec_number); 274 break; 275 276 case A_SETCLASS: 277 au_evclassmap_insert(udata.au_evclass.ec_number, 278 udata.au_evclass.ec_class); 279 break; 280 281 case A_GETPINFO: 282 if (udata.au_aupinfo.ap_pid < 1) 283 return (EINVAL); 284 285 /* XXXAUDIT: p_cansee()? */ 286 if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) 287 return (EINVAL); 288 289 udata.au_aupinfo.ap_auid = tp->p_au->ai_auid; 290 udata.au_aupinfo.ap_mask.am_success = 291 tp->p_au->ai_mask.am_success; 292 udata.au_aupinfo.ap_mask.am_failure = 293 tp->p_au->ai_mask.am_failure; 294 udata.au_aupinfo.ap_termid.machine = 295 tp->p_au->ai_termid.machine; 296 udata.au_aupinfo.ap_termid.port = tp->p_au->ai_termid.port; 297 udata.au_aupinfo.ap_asid = tp->p_au->ai_asid; 298 PROC_UNLOCK(tp); 299 break; 300 301 case A_SETPMASK: 302 if (udata.au_aupinfo.ap_pid < 1) 303 return (EINVAL); 304 305 /* XXXAUDIT: p_cansee()? */ 306 if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) 307 return (EINVAL); 308 309 tp->p_au->ai_mask.am_success = 310 udata.au_aupinfo.ap_mask.am_success; 311 tp->p_au->ai_mask.am_failure = 312 udata.au_aupinfo.ap_mask.am_failure; 313 PROC_UNLOCK(tp); 314 break; 315 316 case A_SETFSIZE: 317 if ((udata.au_fstat.af_filesz != 0) && 318 (udata.au_fstat.af_filesz < MIN_AUDIT_FILE_SIZE)) 319 return (EINVAL); 320 audit_fstat.af_filesz = udata.au_fstat.af_filesz; 321 break; 322 323 case A_GETFSIZE: 324 udata.au_fstat.af_filesz = audit_fstat.af_filesz; 325 udata.au_fstat.af_currsz = audit_fstat.af_currsz; 326 break; 327 328 case A_GETPINFO_ADDR: 329 return (ENOSYS); 330 break; 331 332 case A_GETKAUDIT: 333 return (ENOSYS); 334 break; 335 336 case A_SETKAUDIT: 337 return (ENOSYS); 338 break; 339 340 case A_SENDTRIGGER: 341 if ((udata.au_trigger < AUDIT_TRIGGER_MIN) || 342 (udata.au_trigger > AUDIT_TRIGGER_MAX)) 343 return (EINVAL); 344 return (send_trigger(udata.au_trigger)); 345 } 346 347 /* 348 * Copy data back to userspace for the GET comands. 349 */ 350 switch (uap->cmd) { 351 case A_GETPOLICY: 352 case A_GETKMASK: 353 case A_GETQCTRL: 354 case A_GETCWD: 355 case A_GETCAR: 356 case A_GETSTAT: 357 case A_GETCOND: 358 case A_GETCLASS: 359 case A_GETPINFO: 360 case A_GETFSIZE: 361 case A_GETPINFO_ADDR: 362 case A_GETKAUDIT: 363 error = copyout((void *)&udata, uap->data, uap->length); 364 if (error) 365 return (error); 366 break; 367 } 368 369 return (0); 370 } 371 372 /* 373 * MPSAFE 374 * 375 * System calls to manage the user audit information. 376 */ 377 /* ARGSUSED */ 378 int 379 getauid(struct thread *td, struct getauid_args *uap) 380 { 381 int error; 382 au_id_t id; 383 384 error = suser(td); 385 if (error) 386 return (error); 387 388 /* 389 * XXX: Integer read on static pointer dereference: doesn't need 390 * locking? 391 */ 392 PROC_LOCK(td->td_proc); 393 id = td->td_proc->p_au->ai_auid; 394 PROC_UNLOCK(td->td_proc); 395 return copyout(&id, uap->auid, sizeof(id)); 396 } 397 398 /* MPSAFE */ 399 /* ARGSUSED */ 400 int 401 setauid(struct thread *td, struct setauid_args *uap) 402 { 403 int error; 404 au_id_t id; 405 406 error = suser(td); 407 if (error) 408 return (error); 409 410 error = copyin(uap->auid, &id, sizeof(id)); 411 if (error) 412 return (error); 413 414 audit_arg_auid(id); 415 416 /* 417 * XXX: Integer write on static pointer dereference: doesn't need 418 * locking? 419 * 420 * XXXAUDIT: Might need locking to serialize audit events in the same 421 * order as change events? Or maybe that's an under-solveable 422 * problem. 423 * 424 * XXXRW: Test privilege while holding the proc lock? 425 */ 426 PROC_LOCK(td->td_proc); 427 td->td_proc->p_au->ai_auid = id; 428 PROC_UNLOCK(td->td_proc); 429 430 return (0); 431 } 432 433 /* 434 * MPSAFE 435 * System calls to get and set process audit information. 436 */ 437 /* ARGSUSED */ 438 int 439 getaudit(struct thread *td, struct getaudit_args *uap) 440 { 441 struct auditinfo ai; 442 int error; 443 444 error = suser(td); 445 if (error) 446 return (error); 447 448 PROC_LOCK(td->td_proc); 449 ai = *td->td_proc->p_au; 450 PROC_UNLOCK(td->td_proc); 451 452 return (copyout(&ai, uap->auditinfo, sizeof(ai))); 453 } 454 455 /* MPSAFE */ 456 /* ARGSUSED */ 457 int 458 setaudit(struct thread *td, struct setaudit_args *uap) 459 { 460 struct auditinfo ai; 461 int error; 462 463 error = suser(td); 464 if (error) 465 return (error); 466 467 error = copyin(uap->auditinfo, &ai, sizeof(ai)); 468 if (error) 469 return (error); 470 471 audit_arg_auditinfo(&ai); 472 473 /* 474 * XXXRW: Test privilege while holding the proc lock? 475 */ 476 PROC_LOCK(td->td_proc); 477 *td->td_proc->p_au = ai; 478 PROC_UNLOCK(td->td_proc); 479 480 return (0); 481 } 482 483 /* MPSAFE */ 484 /* ARGSUSED */ 485 int 486 getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) 487 { 488 int error; 489 490 error = suser(td); 491 if (error) 492 return (error); 493 return (ENOSYS); 494 } 495 496 /* MPSAFE */ 497 /* ARGSUSED */ 498 int 499 setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) 500 { 501 int error; 502 503 error = suser(td); 504 if (error) 505 return (error); 506 return (ENOSYS); 507 } 508 509 /* 510 * MPSAFE 511 * Syscall to manage audit files. 512 * 513 * XXX: Should generate an audit event. 514 */ 515 /* ARGSUSED */ 516 int 517 auditctl(struct thread *td, struct auditctl_args *uap) 518 { 519 struct nameidata nd; 520 struct ucred *cred; 521 struct vnode *vp; 522 int error = 0; 523 int flags; 524 525 error = suser(td); 526 if (error) 527 return (error); 528 529 vp = NULL; 530 cred = NULL; 531 532 /* 533 * If a path is specified, open the replacement vnode, perform 534 * validity checks, and grab another reference to the current 535 * credential. 536 * 537 * XXXAUDIT: On Darwin, a NULL path is used to disable audit. 538 */ 539 if (uap->path == NULL) 540 return (EINVAL); 541 542 /* 543 * XXXAUDIT: Giant may no longer be required here. 544 */ 545 mtx_lock(&Giant); 546 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, td); 547 flags = AUDIT_OPEN_FLAGS; 548 error = vn_open(&nd, &flags, 0, -1); 549 if (error) { 550 mtx_unlock(&Giant); 551 goto err_out; 552 } 553 VOP_UNLOCK(nd.ni_vp, 0, td); 554 vp = nd.ni_vp; 555 if (vp->v_type != VREG) { 556 vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); 557 mtx_unlock(&Giant); 558 error = EINVAL; 559 goto err_out; 560 } 561 cred = td->td_ucred; 562 crhold(cred); 563 564 /* 565 * XXXAUDIT: Should audit_suspended actually be cleared by 566 * audit_worker? 567 */ 568 audit_suspended = 0; 569 570 mtx_unlock(&Giant); 571 audit_rotate_vnode(cred, vp); 572 573 err_out: 574 return (error); 575 } 576 577 #else /* !AUDIT */ 578 579 int 580 audit(struct thread *td, struct audit_args *uap) 581 { 582 583 return (ENOSYS); 584 } 585 586 int 587 auditon(struct thread *td, struct auditon_args *uap) 588 { 589 590 return (ENOSYS); 591 } 592 593 int 594 getauid(struct thread *td, struct getauid_args *uap) 595 { 596 597 return (ENOSYS); 598 } 599 600 int 601 setauid(struct thread *td, struct setauid_args *uap) 602 { 603 604 return (ENOSYS); 605 } 606 607 int 608 getaudit(struct thread *td, struct getaudit_args *uap) 609 { 610 611 return (ENOSYS); 612 } 613 614 int 615 setaudit(struct thread *td, struct setaudit_args *uap) 616 { 617 618 return (ENOSYS); 619 } 620 621 int 622 getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) 623 { 624 625 return (ENOSYS); 626 } 627 628 int 629 setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) 630 { 631 632 return (ENOSYS); 633 } 634 635 int 636 auditctl(struct thread *td, struct auditctl_args *uap) 637 { 638 639 return (ENOSYS); 640 } 641 642 void 643 audit_proc_init(struct proc *p) 644 { 645 646 } 647 648 void 649 audit_proc_fork(struct proc *parent, struct proc *child) 650 { 651 652 } 653 654 void 655 audit_proc_free(struct proc *p) 656 { 657 658 } 659 660 #endif /* AUDIT */ 661