Deleted Added
full compact
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 ---