mac_lomac.c (115715) | mac_lomac.c (116701) |
---|---|
1/*- 2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3 * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 4 * All rights reserved. 5 * 6 * This software was developed by Robert Watson for the TrustedBSD Project. 7 * 8 * This software was developed for the FreeBSD Project in part by NAI Labs, --- 17 unchanged lines hidden (view full) --- 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * | 1/*- 2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3 * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 4 * All rights reserved. 5 * 6 * This software was developed by Robert Watson for the TrustedBSD Project. 7 * 8 * This software was developed for the FreeBSD Project in part by NAI Labs, --- 17 unchanged lines hidden (view full) --- 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * |
34 * $FreeBSD: head/sys/security/mac_lomac/mac_lomac.c 115715 2003-06-02 18:49:11Z rwatson $ | 34 * $FreeBSD: head/sys/security/mac_lomac/mac_lomac.c 116701 2003-06-23 01:26:34Z rwatson $ |
35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * Low-watermark floating label mandatory integrity policy. 40 */ 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/acl.h> 45#include <sys/conf.h> 46#include <sys/extattr.h> 47#include <sys/kernel.h> 48#include <sys/mac.h> 49#include <sys/malloc.h> 50#include <sys/mount.h> 51#include <sys/proc.h> | 35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * Low-watermark floating label mandatory integrity policy. 40 */ 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/acl.h> 45#include <sys/conf.h> 46#include <sys/extattr.h> 47#include <sys/kernel.h> 48#include <sys/mac.h> 49#include <sys/malloc.h> 50#include <sys/mount.h> 51#include <sys/proc.h> |
52#include <sys/sbuf.h> |
|
52#include <sys/systm.h> 53#include <sys/sysproto.h> 54#include <sys/sysent.h> 55#include <sys/systm.h> 56#include <sys/vnode.h> 57#include <sys/file.h> 58#include <sys/socket.h> 59#include <sys/socketvar.h> --- 418 unchanged lines hidden (view full) --- 478 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 479 mac_lomac_copy_single(source, dest); 480 if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 481 mac_lomac_copy_auxsingle(source, dest); 482 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 483 mac_lomac_copy_range(source, dest); 484} 485 | 53#include <sys/systm.h> 54#include <sys/sysproto.h> 55#include <sys/sysent.h> 56#include <sys/systm.h> 57#include <sys/vnode.h> 58#include <sys/file.h> 59#include <sys/socket.h> 60#include <sys/socketvar.h> --- 418 unchanged lines hidden (view full) --- 479 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 480 mac_lomac_copy_single(source, dest); 481 if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 482 mac_lomac_copy_auxsingle(source, dest); 483 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 484 mac_lomac_copy_range(source, dest); 485} 486 |
486static int mac_lomac_to_string(char *string, size_t size, 487 size_t *caller_len, struct mac_lomac *mac_lomac); | 487static int mac_lomac_to_string(struct sbuf *sb, 488 struct mac_lomac *mac_lomac); |
488 489static int 490maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 491 const char *actionname, const char *objname, struct vnode *vpq) 492{ | 489 490static int 491maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 492 const char *actionname, const char *objname, struct vnode *vpq) 493{ |
494 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 495 char *subjlabeltext, *objlabeltext, *subjtext; 496 struct mac_lomac cached_subjlabel; 497 struct mac_lomac_proc *subj; |
|
493 struct vattr va; | 498 struct vattr va; |
494 static char xxx[] = "<<XXX>>"; 495 struct mac_lomac_proc *subj = PSLOT(&curthread->td_proc->p_label); 496 char *subjlabeltext, *objlabeltext, *subjtext, *text; | |
497 struct proc *p; | 499 struct proc *p; |
498 size_t len; | |
499 pid_t pgid; 500 | 500 pid_t pgid; 501 |
502 subj = PSLOT(&curthread->td_proc->p_label); 503 |
|
501 p = curthread->td_proc; 502 mtx_lock(&subj->mtx); 503 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 504 /* 505 * Check to see if the pending demotion would be more or 506 * less severe than this one, and keep the more severe. 507 * This can only happen for a multi-threaded application. 508 */ --- 17 unchanged lines hidden (view full) --- 526 &subj->mac_lomac.ml_rangelow)) 527 subj->mac_lomac.ml_rangelow = objlabel->ml_single; 528 subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 529 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 530 mtx_lock_spin(&sched_lock); 531 curthread->td_flags |= TDF_ASTPENDING; 532 curthread->td_proc->p_sflag |= PS_MACPEND; 533 mtx_unlock_spin(&sched_lock); | 504 p = curthread->td_proc; 505 mtx_lock(&subj->mtx); 506 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 507 /* 508 * Check to see if the pending demotion would be more or 509 * less severe than this one, and keep the more severe. 510 * This can only happen for a multi-threaded application. 511 */ --- 17 unchanged lines hidden (view full) --- 529 &subj->mac_lomac.ml_rangelow)) 530 subj->mac_lomac.ml_rangelow = objlabel->ml_single; 531 subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 532 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 533 mtx_lock_spin(&sched_lock); 534 curthread->td_flags |= TDF_ASTPENDING; 535 curthread->td_proc->p_sflag |= PS_MACPEND; 536 mtx_unlock_spin(&sched_lock); |
534 subjtext = subjlabeltext = objlabeltext = xxx; 535 if (mac_lomac_to_string(NULL, 0, &len, &subj->mac_lomac) == 0 && 536 (text = malloc(len + 1, M_MACLOMAC, M_NOWAIT)) != NULL) { 537 if (mac_lomac_to_string(text, len + 1, &len, 538 &subj->mac_lomac) == 0) 539 subjtext = text; 540 else 541 free(text, M_MACLOMAC); 542 } | 537 538 /* 539 * Avoid memory allocation while holding a mutex; cache the 540 * label. 541 */ 542 mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); |
543 mtx_unlock(&subj->mtx); | 543 mtx_unlock(&subj->mtx); |
544 if (mac_lomac_to_string(NULL, 0, &len, subjlabel) == 0 && 545 (text = malloc(len + 1, M_MACLOMAC, M_NOWAIT)) != NULL) { 546 if (mac_lomac_to_string(text, len + 1, &len, 547 subjlabel) == 0) 548 subjlabeltext = text; 549 else 550 free(text, M_MACLOMAC); 551 } 552 if (mac_lomac_to_string(NULL, 0, &len, objlabel) == 0 && 553 (text = malloc(len + 1, M_MACLOMAC, M_NOWAIT)) != NULL) { 554 if (mac_lomac_to_string(text, len + 1, &len, 555 objlabel) == 0) 556 objlabeltext = text; 557 else 558 free(text, M_MACLOMAC); 559 } | 544 545 sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 546 mac_lomac_to_string(&subjlabel_sb, subjlabel); 547 sbuf_finish(&subjlabel_sb); 548 subjlabeltext = sbuf_data(&subjlabel_sb); 549 550 sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 551 mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac); 552 sbuf_finish(&subjtext_sb); 553 subjtext = sbuf_data(&subjtext_sb); 554 555 sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 556 mac_lomac_to_string(&objlabel_sb, objlabel); 557 sbuf_finish(&objlabel_sb); 558 objlabeltext = sbuf_data(&objlabel_sb); 559 |
560 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 561 if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred, 562 curthread) == 0) { 563 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 564 " level %s after %s a level-%s %s (inode=%ld, " 565 "mountpount=%s)\n", 566 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 567 p->p_comm, subjtext, actionname, objlabeltext, objname, 568 va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname); 569 } else { 570 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 571 " level %s after %s a level-%s %s\n", 572 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 573 p->p_comm, subjtext, actionname, objlabeltext, objname); 574 } | 560 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 561 if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred, 562 curthread) == 0) { 563 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 564 " level %s after %s a level-%s %s (inode=%ld, " 565 "mountpount=%s)\n", 566 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 567 p->p_comm, subjtext, actionname, objlabeltext, objname, 568 va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname); 569 } else { 570 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 571 " level %s after %s a level-%s %s\n", 572 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 573 p->p_comm, subjtext, actionname, objlabeltext, objname); 574 } |
575 576 sbuf_delete(&subjlabel_sb); 577 sbuf_delete(&subjtext_sb); 578 sbuf_delete(&objlabel_sb); |
|
575 | 579 |
576 if (subjlabeltext != xxx) 577 free(subjlabeltext, M_MACLOMAC); 578 if (objlabeltext != xxx) 579 free(objlabeltext, M_MACLOMAC); 580 if (subjtext != xxx) 581 free(subjtext, M_MACLOMAC); | |
582 return (0); 583} 584 585/* 586 * Relabel "to" to "from" only if "from" is a valid label (contains 587 * at least a single), as for a relabel operation which may or may 588 * not involve a relevant label. 589 */ --- 64 unchanged lines hidden (view full) --- 654mac_lomac_destroy_proc_label(struct label *label) 655{ 656 657 mtx_destroy(&PSLOT(label)->mtx); 658 FREE(PSLOT(label), M_MACLOMAC); 659 PSLOT(label) = NULL; 660} 661 | 580 return (0); 581} 582 583/* 584 * Relabel "to" to "from" only if "from" is a valid label (contains 585 * at least a single), as for a relabel operation which may or may 586 * not involve a relevant label. 587 */ --- 64 unchanged lines hidden (view full) --- 652mac_lomac_destroy_proc_label(struct label *label) 653{ 654 655 mtx_destroy(&PSLOT(label)->mtx); 656 FREE(PSLOT(label), M_MACLOMAC); 657 PSLOT(label) = NULL; 658} 659 |
662/* 663 * mac_lomac_element_to_string() is basically an snprintf wrapper with 664 * the same properties as snprintf(). It returns the length it would 665 * have added to the string in the event the string is too short. 666 */ 667static size_t 668mac_lomac_element_to_string(char *string, size_t size, 669 struct mac_lomac_element *element) | 660static int 661mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) |
670{ 671 672 switch (element->mle_type) { 673 case MAC_LOMAC_TYPE_HIGH: | 662{ 663 664 switch (element->mle_type) { 665 case MAC_LOMAC_TYPE_HIGH: |
674 return (snprintf(string, size, "high")); | 666 return (sbuf_printf(sb, "high")); |
675 676 case MAC_LOMAC_TYPE_LOW: | 667 668 case MAC_LOMAC_TYPE_LOW: |
677 return (snprintf(string, size, "low")); | 669 return (sbuf_printf(sb, "low")); |
678 679 case MAC_LOMAC_TYPE_EQUAL: | 670 671 case MAC_LOMAC_TYPE_EQUAL: |
680 return (snprintf(string, size, "equal")); | 672 return (sbuf_printf(sb, "equal")); |
681 682 case MAC_LOMAC_TYPE_GRADE: | 673 674 case MAC_LOMAC_TYPE_GRADE: |
683 return (snprintf(string, size, "%d", element->mle_grade)); | 675 return (sbuf_printf(sb, "%d", element->mle_grade)); |
684 685 default: 686 panic("mac_lomac_element_to_string: invalid type (%d)", 687 element->mle_type); 688 } 689} 690 691static int | 676 677 default: 678 panic("mac_lomac_element_to_string: invalid type (%d)", 679 element->mle_type); 680 } 681} 682 683static int |
692mac_lomac_to_string(char *string, size_t size, size_t *caller_len, 693 struct mac_lomac *mac_lomac) | 684mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac) |
694{ | 685{ |
695 size_t left, len, curlen; 696 char *curptr; | |
697 | 686 |
698 /* 699 * Also accept NULL string to allow for predetermination of total 700 * string length. 701 */ 702 if (string != NULL) 703 bzero(string, size); 704 else if (size != 0) 705 return (EINVAL); 706 curptr = string; 707 left = size; 708 curlen = 0; 709 710#define INCLEN(length, leftover) do { \ 711 if (string != NULL) { \ 712 if (length >= leftover) \ 713 return (EINVAL); \ 714 leftover -= length; \ 715 curptr += length; \ 716 } \ 717 curlen += length; \ 718} while (0) | |
719 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { | 687 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { |
720 len = mac_lomac_element_to_string(curptr, left, 721 &mac_lomac->ml_single); 722 INCLEN(len, left); | 688 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single) 689 == -1) 690 return (EINVAL); |
723 } 724 725 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { | 691 } 692 693 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { |
726 len = snprintf(curptr, left, "["); 727 INCLEN(len, left); | 694 if (sbuf_putc(sb, '[') == -1) 695 return (EINVAL); |
728 | 696 |
729 len = mac_lomac_element_to_string(curptr, left, 730 &mac_lomac->ml_auxsingle); 731 INCLEN(len, left); | 697 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle) 698 == -1) 699 return (EINVAL); |
732 | 700 |
733 len = snprintf(curptr, left, "]"); 734 INCLEN(len, left); | 701 if (sbuf_putc(sb, ']') == -1) 702 return (EINVAL); |
735 } 736 737 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { | 703 } 704 705 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { |
738 len = snprintf(curptr, left, "("); 739 INCLEN(len, left); | 706 if (sbuf_putc(sb, '(') == -1) 707 return (EINVAL); |
740 | 708 |
741 len = mac_lomac_element_to_string(curptr, left, 742 &mac_lomac->ml_rangelow); 743 INCLEN(len, left); | 709 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow) 710 == -1) 711 return (EINVAL); |
744 | 712 |
745 len = snprintf(curptr, left, "-"); 746 INCLEN(len, left); | 713 if (sbuf_putc(sb, '-') == -1) 714 return (EINVAL); |
747 | 715 |
748 len = mac_lomac_element_to_string(curptr, left, 749 &mac_lomac->ml_rangehigh); 750 INCLEN(len, left); | 716 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh) 717 == -1) 718 return (EINVAL); |
751 | 719 |
752 len = snprintf(curptr, left, ")"); 753 INCLEN(len, left); | 720 if (sbuf_putc(sb, '-') == -1) 721 return (EINVAL); |
754 } | 722 } |
755#undef INCLEN | |
756 | 723 |
757 *caller_len = curlen; | |
758 return (0); 759} 760 761static int 762mac_lomac_externalize_label(struct label *label, char *element_name, | 724 return (0); 725} 726 727static int 728mac_lomac_externalize_label(struct label *label, char *element_name, |
763 char *element_data, size_t size, size_t *len, int *claimed) | 729 struct sbuf *sb, int *claimed) |
764{ 765 struct mac_lomac *mac_lomac; | 730{ 731 struct mac_lomac *mac_lomac; |
766 int error; | |
767 768 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 769 return (0); 770 771 (*claimed)++; 772 773 mac_lomac = SLOT(label); | 732 733 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 734 return (0); 735 736 (*claimed)++; 737 738 mac_lomac = SLOT(label); |
774 error = mac_lomac_to_string(element_data, size, len, mac_lomac); 775 if (error) 776 return (error); | |
777 | 739 |
778 *len = strlen(element_data); 779 return (0); | 740 return (mac_lomac_to_string(sb, mac_lomac)); |
780} 781 782static int 783mac_lomac_parse_element(struct mac_lomac_element *element, char *string) 784{ 785 786 if (strcmp(string, "high") == 0 || 787 strcmp(string, "hi") == 0) { --- 1949 unchanged lines hidden --- | 741} 742 743static int 744mac_lomac_parse_element(struct mac_lomac_element *element, char *string) 745{ 746 747 if (strcmp(string, "high") == 0 || 748 strcmp(string, "hi") == 0) { --- 1949 unchanged lines hidden --- |