Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Oct 2003 19:03:57 -0700 (PDT)
From:      Chris Vance <cvance@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 39487 for review
Message-ID:  <200310110203.h9B23v9r049170@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39487

Change 39487 by cvance@cvance_osx_laptop on 2003/10/10 19:03:16

	Copy from sebsd branch, initial import

Affected files ...

.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/Makefile#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/av_inherit.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/av_perm_to_string.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/av_permissions.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/avc.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/avc.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/avc_ss.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/class_to_string.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/common_perm_to_string.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/avc/initial_sid_to_string.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask/Makefile#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask/README#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask/access_vectors#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask/initial_sids#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask/mkaccess_vector.sh#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask/mkflask.sh#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask/security_classes#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/flask_types.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/linux-compat.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_labels.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_syscall.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_syscalls.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd_sysctl.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/avtab.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/avtab.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/constraint.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/context.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/ebitmap.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/ebitmap.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/fileutils.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/fileutils.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/global.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/hashtab.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/hashtab.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/init.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/mls.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/mls.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/mls_types.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/policydb.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/policydb.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/queue.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/queue.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/security.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/services.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/services.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/services_private.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/sidtab.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/sidtab.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/symtab.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/ss/symtab.h#1 add

Differences ...

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/Makefile#2 (text+ko) ====

@@ -7,22 +7,29 @@
 include $(MakeInc_cmd)
 include $(MakeInc_def)
 
-INSTINC_SUBDIRS =
+EXPORT_ONLY_FILES = \
+	sebsd.h \
+	flask.h \
+	flask_types.h \
+	linux-compat.h
+
+INSTINC_SUBDIRS = avc ss
 INSTINC_SUBDIRS_PPC = ${INSTINC_SUBDIRS}
 INSTINC_SUBDIRS_I386 = ${INSTINC_SUBDIRS}
 
-EXPINC_SUBDIRS = 
+EXPINC_SUBDIRS = avc ss
 EXPINC_SUBDIRS_PPC = ${EXPINC_SUBDIRS} 
 EXPINC_SUBDIRS_I386 = ${EXPINC_SUBDIRS} 
 
 INSTALL_MI_LIST	= 
 
-INSTALL_MI_DIR = 
+INSTALL_MI_DIR = sebsd
 
-EXPORT_MI_LIST	= 
+EXPORT_MI_LIST = ${EXPORT_ONLY_FILES}
 
-EXPORT_MI_DIR = 
+EXPORT_MI_DIR = sebsd
 
+INCFLAGS_MAKEFILE= -I..
 
 include $(MakeInc_rule)
 include $(MakeInc_dir)

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd.c#2 (text+ko) ====

@@ -1,1 +1,2151 @@
-char *sebsd_id = "SEBSD Module";
+/*-
+ * Copyright (c) 2002, 2003 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by NAI Labs, the
+ * Security Research Division of Network Associates, Inc. under
+ * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
+ * CHATS research program.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/extattr.h>
+#include <sys/imgact.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/mac.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/sbuf.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/vnode.h>
+#include <sys/pipe.h>
+#include <sys/dirent.h>
+#include <sys/capability.h>
+
+#include <fs/devfs/devfs.h>
+
+#include <vm/vm.h>
+
+#include <sys/mac_policy.h>
+
+#include <security/sebsd/sebsd.h>
+#include <security/sebsd/sebsd_labels.h>
+
+int sebsd_verbose = 0;
+
+static int slot;
+#define	SLOT(l)	((void *)LABEL_TO_SLOT((l), slot).l_ptr)
+
+MALLOC_DEFINE(M_SEBSD, "sebsd", "Security Enhanced BSD");
+
+extern int ss_initialized;
+static __inline int ss_precondition(void)
+{
+	return ss_initialized;
+}
+
+static void
+sebsd_init(struct mac_policy_conf *mpc)
+{
+	printf("sebsd:: init\n");
+	avc_init();
+	if (security_init()) {
+		panic("SEBSD: couldn't read policy file");
+	}
+}
+
+static void
+sebsd_destroy(struct mac_policy_conf *mpc)
+{
+
+	printf("sebsd:: destroy\n");
+}
+
+/*
+ * Check whether a task is allowed to use a capability.
+ */
+static int
+cred_has_capability(struct ucred *cred, cap_value_t cap)
+{
+	struct task_security_struct *task;
+	struct avc_audit_data ad;
+
+	task = SLOT(&cred->cr_label);
+
+	AVC_AUDIT_DATA_INIT(&ad, CAP);
+	ad.u.cap = cap;
+
+	return avc_has_perm_audit(task->sid, task->sid,
+	    SECCLASS_CAPABILITY, cap, &ad);
+}
+
+static int
+cred_has_perm(struct ucred *cred, struct proc *proc, access_vector_t perm)
+{
+	struct task_security_struct *task, *target;
+
+	task = SLOT(&cred->cr_label);
+	target = SLOT(&proc->p_ucred->cr_label);
+
+	return (avc_has_perm_ref(task->sid, target->sid, SECCLASS_PROCESS,
+	    perm, &target->avcr));
+}
+
+static int
+mount_has_perm(struct ucred *cred, struct mount *mp, access_vector_t perm,
+    struct avc_audit_data *ad)
+{
+	struct mount_security_struct *sbsec;
+	struct task_security_struct *task;
+
+	task = SLOT(&cred->cr_label);
+	sbsec = SLOT(&mp->mnt_mntlabel);
+
+	return (avc_has_perm_audit(task->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+	    perm, ad));
+}
+
+static int
+cred_has_system(struct ucred *cred, access_vector_t perm)
+{
+	struct task_security_struct *task;
+
+	task = SLOT(&cred->cr_label);
+
+	return (avc_has_perm(task->sid, SECINITSID_KERNEL,
+	    SECCLASS_SYSTEM, perm, NULL, NULL));
+}
+
+static int
+cred_has_security(struct ucred *cred, access_vector_t perm)
+{
+	struct task_security_struct *task;
+
+	task = SLOT(&cred->cr_label);
+
+	return (avc_has_perm(task->sid, SECINITSID_SECURITY,
+	    SECCLASS_SECURITY, perm, NULL, NULL));
+}
+
+int
+thread_has_system(struct thread *td, access_vector_t perm)
+{
+
+	return (cred_has_system(td->td_proc->p_ucred, perm));
+}
+
+int
+thread_has_security(struct thread *td, access_vector_t perm)
+{
+
+	return (cred_has_security(td->td_proc->p_ucred, perm));
+}
+
+static __inline security_class_t
+vnode_type_to_security_class(enum vtype vt)
+{
+	switch (vt) {
+	case VREG:
+		return SECCLASS_FILE;
+	case VDIR:
+		return SECCLASS_DIR;
+	case VBLK:
+		return SECCLASS_BLK_FILE;
+	case VCHR:
+		return SECCLASS_CHR_FILE;
+	case VLNK:
+		return SECCLASS_LNK_FILE;
+	case VSOCK:
+		return SECCLASS_SOCK_FILE;
+	case VFIFO:
+		return SECCLASS_FIFO_FILE;
+	case VNON:
+	case VBAD:
+		return SECCLASS_FILE;
+	}
+
+	return SECCLASS_FILE;
+}
+
+static __inline security_class_t
+dirent_type_to_security_class(__uint8_t type)
+{
+	switch (type) {
+	case DT_REG:
+		return SECCLASS_FILE;
+	case DT_DIR:
+		return SECCLASS_DIR;
+	case DT_BLK:
+		return SECCLASS_BLK_FILE;
+	case DT_CHR:
+		return SECCLASS_CHR_FILE;
+	case DT_LNK:
+		return SECCLASS_LNK_FILE;
+	case DT_SOCK:
+		return SECCLASS_SOCK_FILE;
+	case DT_FIFO:
+		return SECCLASS_FIFO_FILE;
+	case DT_UNKNOWN:
+	case DT_WHT:
+		return SECCLASS_FILE;
+	}
+
+	return SECCLASS_FILE;
+}
+
+static __inline access_vector_t
+file_mask_to_av(enum vtype vt, int mask)
+{
+	access_vector_t av = 0;
+
+	if (vt != VDIR) {
+		if (mask & VEXEC)
+			av |= FILE__EXECUTE;
+		if (mask & VREAD)
+			av |= FILE__READ;
+
+		if (mask & VAPPEND)
+			av |= FILE__APPEND;
+		else if (mask & VWRITE)
+			av |= FILE__WRITE;
+
+	} else {
+		if (mask & VEXEC)
+			av |= DIR__SEARCH;
+		if (mask & VWRITE)
+			av |= DIR__WRITE;
+		if (mask & VREAD)
+			av |= DIR__READ;
+	}
+
+	return av;
+}
+
+static int
+vnode_has_perm(struct ucred *cred, struct vnode *vp, access_vector_t perm,
+    struct avc_entry_ref *aeref)
+{
+	struct task_security_struct *task;
+	struct vnode_security_struct *file;
+	struct avc_audit_data ad;
+
+	task = SLOT(&cred->cr_label);
+	file = SLOT(&vp->v_label);
+
+	AVC_AUDIT_DATA_INIT(&ad, FS);
+	ad.u.fs.vp = vp;
+
+	if (file->sclass == 0) {
+		struct vattr va;
+		VOP_GETATTR(vp, &va, curthread->td_ucred, curthread);
+		printf("vnode_has_perm:: ERROR, sid=%d, sclass=0, v_type=%d,"
+		       " inode=%ld, fsid=%d\n",
+		       file->sid, vp->v_type, va.va_fileid, va.va_fsid);
+		file->sclass = vnode_type_to_security_class(vp->v_type);
+		if (file->sclass == 0) {
+			printf("vnode_has_perm:: Giving up\n");
+			return 1; /* TBD: debugging */
+		}
+	}
+	return avc_has_perm_ref_audit(task->sid, file->sid, file->sclass,
+				      perm, aeref ? aeref : &file->avcr, &ad);
+}
+
+static int
+pipe_has_perm(struct ucred *cred, struct pipe *pipe, access_vector_t perm)
+{
+	struct task_security_struct *task;
+	struct vnode_security_struct *file;
+
+	task = SLOT(&cred->cr_label);
+	file = SLOT(pipe->pipe_label);
+
+	/*
+	 * TBD: No audit information yet
+	 */
+
+	return(avc_has_perm_ref(task->sid, file->sid, file->sclass,
+	    perm, &file->avcr));
+}
+
+static void
+sebsd_init_cred_label(struct label *label)
+{
+	struct task_security_struct *new_tsec;
+
+	new_tsec = malloc(sizeof(*new_tsec), M_SEBSD, M_ZERO | M_WAITOK);
+	new_tsec->osid = new_tsec->sid = SECINITSID_UNLABELED;
+	SLOT(label) = new_tsec;
+}
+
+static void
+sebsd_init_file_label(struct label *label)
+{
+	struct file_security_struct *new_fsec;
+
+	new_fsec = malloc(sizeof(*new_fsec), M_SEBSD, M_ZERO | M_WAITOK);
+	new_fsec->sid = new_fsec->sid = SECINITSID_UNLABELED;
+	SLOT(label) = new_fsec;
+}
+
+static void
+sebsd_init_mount_label(struct label *label)
+{
+	struct mount_security_struct *sbsec;
+
+	sbsec = malloc(sizeof(*sbsec), M_SEBSD, M_ZERO | M_WAITOK);
+	sbsec->sid = SECINITSID_UNLABELED;
+	SLOT(label) = sbsec;
+}
+
+static void
+sebsd_init_mount_fs_label(struct label *label)
+{
+	struct mount_fs_security_struct *sbsec;
+
+	sbsec = malloc(sizeof(*sbsec), M_SEBSD, M_ZERO | M_WAITOK);
+	sbsec->sid = SECINITSID_UNLABELED;
+	SLOT(label) = sbsec;
+}
+
+static void
+sebsd_init_network_label(struct label *label)
+{
+	struct network_security_struct *new;
+
+	new = malloc(sizeof(*new), M_SEBSD, M_ZERO | M_WAITOK);
+	new->sid = new->task_sid = SECINITSID_UNLABELED;
+	SLOT(label) = new;
+}
+
+static int
+sebsd_init_network_label_waitcheck(struct label *label, int flag)
+{
+	struct network_security_struct *new;
+
+	new = malloc(sizeof(*new), M_SEBSD, M_ZERO | flag);
+	if (new == NULL) {
+		SLOT(label) = NULL;
+		return (ENOMEM);
+	}
+
+	new->sid = new->task_sid = SECINITSID_UNLABELED;
+	SLOT(label) = new;
+
+	return (0);
+}
+
+static void
+sebsd_init_vnode_label(struct label *label)
+{
+	struct vnode_security_struct *vsec;
+
+	vsec = malloc(sizeof(*vsec), M_SEBSD, M_ZERO | M_WAITOK);
+	vsec->sid = SECINITSID_UNLABELED;
+	vsec->task_sid = SECINITSID_UNLABELED;
+	SLOT(label) = vsec;
+}
+
+static void
+sebsd_destroy_label(struct label *label)
+{
+
+	free(SLOT(label), M_SEBSD);
+	SLOT(label) = NULL;
+}
+
+static void
+sebsd_relabel_cred(struct ucred *cred, struct label *newlabel)
+{
+
+	printf("sebsd_relabel_cred:: This does nothing\n");
+}
+
+static void
+sebsd_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
+    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
+    struct label *vlabel)
+{
+	struct vnode_security_struct *vsec, *dsec;
+
+	dsec = SLOT(delabel);
+	vsec = SLOT(vlabel);
+
+	vsec->sid = dsec->sid;
+	vsec->task_sid = dsec->task_sid;
+	vsec->sclass = dsec->sclass;
+
+	/*
+	 * This is a no-op for now, but when devfs_dirents do contain
+	 * labels, they should be copied to the vp here as per how
+	 * sebsd_update_vnode_from_extattr() functions.  They will be
+	 * kept synchronized from here on automatically with the vnode
+	 * relabel calls.
+	 */
+}
+
+static int
+sebsd_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
+    struct vnode *vp, struct label *vlabel)
+{
+	struct vnode_security_struct *vsec;
+	/* TBD: Need to limit size of contexts used in extattr labels */
+	char context[128];
+	u_int32_t context_len;
+	int error;
+
+	vsec = SLOT(vlabel);
+
+	context_len = sizeof(context); /* TBD: bad fixed length */
+	error = vn_extattr_get(vp, IO_NODELOCKED,
+			       SEBSD_MAC_EXTATTR_NAMESPACE,
+			       SEBSD_MAC_EXTATTR_NAME,
+			       &context_len, context, curthread);
+	if (error == ENOATTR || error == EOPNOTSUPP) {
+		vsec->sid = SECINITSID_UNLABELED; /* Use the default label */
+
+		/*
+		struct vattr va;
+
+		(void)VOP_GETATTR(vp, &va, curthread->td_ucred, curthread);
+		printf("sebsd_update_vnode_from_extattr: no label for "
+		       "inode=%ld, fsid=%d\n", va.va_fileid, va.va_fsid);
+		*/
+		goto dosclass;
+	}
+	if (error) {
+		printf("sebsd_update_vnode_from_extattr: ERROR %d returned "
+		    " by vn_extattr_get()\n", error);
+		return (error); /* Fail closed */
+	}
+	if (sebsd_verbose > 1) {
+		struct vattr va;
+
+		VOP_GETATTR(vp, &va, curthread->td_ucred, curthread);
+		printf("sebsd_vnode_from_extattr: len=%d: context=%.*s "
+		       "inode=%ld, fsid=%d\n", context_len, context_len,
+			context, va.va_fileid, va.va_fsid);
+	}
+
+	error = security_context_to_sid(context, context_len, &vsec->sid);
+	if (error) {
+		printf("sebsd_update_vnode_from_extattr: ERROR mapping "
+		       "context to sid: %.*s\n", context_len, context);
+		return (0); /* TBD bad, bad, bad */
+	}
+
+dosclass:
+	/* TBD:	 */
+ 	vsec->sclass = vnode_type_to_security_class(vp->v_type);
+	if (vsec->sclass == 0) {
+		printf("sebsd_update_vnode_from_extattr:: sclass is 0\n");
+	}
+
+	return (0);
+}
+
+static void
+sebsd_associate_vnode_singlelabel(struct mount *mp, struct label *fslabel,
+				  struct vnode *vp, struct label *vlabel)
+{
+	struct mount_fs_security_struct *sbsec;
+	struct vnode_security_struct *vsec;
+
+	sbsec = SLOT(fslabel);
+	vsec = SLOT(vlabel);
+	vsec->sid = sbsec->sid;
+ 	vsec->sclass = vnode_type_to_security_class(vp->v_type);
+}
+
+static void
+sebsd_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
+{
+	int rc;
+	struct task_security_struct *parent, *task;
+
+	rc = ss_precondition();
+	if (rc <= 0)
+		return;
+
+	parent = SLOT(&cred_parent->cr_label);
+	task = SLOT(&cred_child->cr_label);
+
+	/* Default to using the attributes from the parent process */
+	task->osid = parent->osid;
+	task->sid = parent->sid;
+
+	return;
+}
+
+static void
+sebsd_create_file(struct ucred *cred, struct file *fp, struct label *label)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(label);
+
+	fsec->sid = tsec->sid;
+}
+
+static void
+sebsd_create_devfs_device(struct ucred *cr, struct mount *mp, dev_t dev,
+    struct devfs_dirent *devfs_dirent, struct label *label,
+    const char *fullpath)
+{
+	char *path;
+	int rc;
+	security_id_t newsid;
+	struct mount_security_struct *sbsec;
+	struct vnode_security_struct *dirent;
+
+	dirent = SLOT(label);
+	sbsec = SLOT(&mp->mnt_mntlabel);
+
+	/* Default to the filesystem SID. */
+	dirent->sid = sbsec->sid;
+	dirent->task_sid = SECINITSID_KERNEL;
+	dirent->sclass =
+	    dirent_type_to_security_class(devfs_dirent->de_dirent->d_type);
+
+	/* Obtain a SID based on the fstype, path, and class. */
+	path = malloc(strlen(fullpath) + 2, M_SEBSD, M_ZERO | M_WAITOK);
+	path[0] = '/';
+	strcpy(&path[1], fullpath);
+	rc = security_genfs_sid(mp->mnt_vfc->vfc_name, path, dirent->sclass,
+	    &newsid);
+
+	if (rc == 0)
+		dirent->sid = newsid;
+
+	/* If there was a creating process (currently only for /dev/pty*),
+	   try a type_transition rule. */
+	if (cr != NULL) {
+		struct task_security_struct *task = SLOT(&cr->cr_label);
+
+		/* XXX: uses the type specified by genfs instead of the parent directory
+		   like it should! */
+		int error = security_transition_sid(task->sid, dirent->sid, dirent->sclass,
+		    &newsid);
+		if (error == 0)
+			dirent->sid = newsid;
+	}
+
+	/* TBD: debugging */
+	if (sebsd_verbose > 1) {
+		printf("sebsd_create_devfs_device(%s): sbsid=%d, "
+		    "mountpoint=%s, rc=%d, sclass=%d, computedsid=%d, "
+		    "dirent=%d\n", path, sbsec->sid, mp->mnt_stat.f_mntonname,
+		    rc, dirent->sclass, newsid, dirent->sid);
+	}
+	free(path, M_SEBSD);
+}
+
+static void
+sebsd_create_devfs_directory(struct mount *mp, char *dirname,
+    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label,
+    const char *fullpath)
+{
+	char *path;
+	int rc;
+	security_id_t newsid;
+	struct mount_security_struct *sbsec;
+	struct vnode_security_struct *dirent;
+
+	dirent = SLOT(label);
+	sbsec = SLOT(&mp->mnt_mntlabel);
+
+	/* Default to the filesystem SID. */
+	dirent->sid = sbsec->sid;
+	dirent->task_sid = SECINITSID_KERNEL;
+	dirent->sclass = SECCLASS_DIR;
+
+	/* Obtain a SID based on the fstype, path, and class. */
+	path = malloc(strlen(fullpath) + 2, M_SEBSD, M_ZERO | M_WAITOK);
+	path[0] = '/';
+	strcpy(&path[1], fullpath);
+	rc = security_genfs_sid(mp->mnt_vfc->vfc_name, path, dirent->sclass,
+	    &newsid);
+	if (rc == 0)
+		dirent->sid = newsid;
+
+	/* TBD: debugging */
+	if (sebsd_verbose > 1) {
+		printf("%s(%s): sbsid=%d, mountpoint=%s, "
+		    "rc=%d, sclass=%d, computedsid=%d, dirent=%d\n",
+		    __func__, path, sbsec->sid, mp->mnt_stat.f_mntonname, rc,
+		    dirent->sclass, newsid, dirent->sid);
+	}
+	free(path, M_SEBSD);
+}
+
+static void
+sebsd_create_devfs_symlink(struct ucred *cred, struct mount *mp,
+    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
+    struct label *delabel, const char *fullpath)
+{
+
+	char *path;
+	int rc;
+	security_id_t newsid;
+	struct vnode_security_struct *lnksec;
+	struct vnode_security_struct *dirsec;
+	struct mount_security_struct *sbsec;
+
+	/* TBD: Should probably be checking MAY_LINK/MAY_CREATE perms here */
+
+	dirsec = SLOT(ddlabel);
+	lnksec = SLOT(delabel);
+	sbsec = SLOT(&mp->mnt_mntlabel);
+
+	/* Default to the filesystem SID. */
+	lnksec->sid = dirsec->sid;
+	lnksec->task_sid = SECINITSID_KERNEL;
+	lnksec->sclass = SECCLASS_LNK_FILE;
+
+	/* Obtain a SID based on the fstype, path, and class. */
+	path = malloc(strlen(fullpath) + 2, M_SEBSD, M_ZERO | M_WAITOK);
+	path[0] = '/';
+	strcpy(&path[1], fullpath);
+	rc = security_genfs_sid(mp->mnt_vfc->vfc_name, path, lnksec->sclass,
+	    &newsid);
+	if (rc == 0)
+		lnksec->sid = newsid;
+
+	if (sebsd_verbose > 1) {
+		printf("%s(%s): sbsid=%d, mountpoint=%s, rc=%d, sclass=%d, "
+		    "computedsid=%d, dirent=%d\n", __func__, path,
+		    sbsec->sid, mp->mnt_stat.f_mntonname, rc,
+		    lnksec->sclass, newsid, lnksec->sid);
+	}
+	free(path, M_SEBSD);
+}
+
+/*
+ * Use the allocating task SID to label pipes.  On Linux, pipes reside
+ * in a pseudo filesystem.
+ */
+static void
+sebsd_create_pipe(struct ucred *cred, struct pipe *pipe,
+   struct label *pipelabel)
+{
+	struct task_security_struct *tsec;
+	struct vnode_security_struct *vsec;
+
+	tsec = SLOT(&cred->cr_label);
+	vsec = SLOT(pipelabel);
+
+	vsec->sid = vsec->task_sid = tsec->sid;
+	vsec->sclass = SECCLASS_FIFO_FILE;
+}
+
+static void
+sebsd_create_proc0(struct ucred *cred)
+{
+	struct task_security_struct *task;
+
+	task = SLOT(&cred->cr_label);
+	task->osid = task->sid = SECINITSID_KERNEL;
+	printf("sebsd_create_proc0:: using SECINITSID_KERNEL = %d\n",
+	       SECINITSID_KERNEL);
+}
+
+static void
+sebsd_create_proc1(struct ucred *cred)
+{
+	struct task_security_struct *task;
+
+	task = SLOT(&cred->cr_label);
+	task->osid = SECINITSID_KERNEL;
+	task->sid = SECINITSID_INIT;
+	printf("sebsd_create_proc1:: using SICINITSID_INIT = %d\n",
+	       SECINITSID_INIT);
+}
+
+static void
+sebsd_create_mount(struct ucred *cred, struct mount *mp,
+    struct label *mntlabel, struct label *fslabel, struct label *mount_arg_label)
+{
+	struct mount_security_struct *sbsec, *mntsec;
+	struct mount_fs_security_struct *sbfssec;
+	int behavior, rc;
+
+	sbsec = SLOT(mntlabel);
+	sbfssec = SLOT(fslabel);
+	/* TBD TBD TBD */
+	/*
+	 * Make the label for the filesystem the same as the singlelabel
+	 * which the filesystem will use if not a "multilabel" type.
+	 */
+	rc = security_fs_use(mp->mnt_vfc->vfc_name, &behavior, &sbsec->sid);
+	if (rc) {
+		printf("sebsd_create_mount: security_fs_use(%s) returned %d\n",
+		    mp->mnt_vfc->vfc_name, rc);
+		behavior = SECURITY_FS_USE_NONE;
+	} else {
+		sbfssec->sid = sbsec->sid;
+		/* TBD: debugging only */
+		printf("sebsd_create_mount: security_fs_use(%s) behavior %d, sid %d\n",
+		    mp->mnt_vfc->vfc_name, behavior, sbsec->sid);
+	}
+
+	switch (behavior) {
+	case SECURITY_FS_USE_XATTR:
+		/* PSIDs only work for persistent file systems with
+		   unique and persistent inode numbers. */
+		sbsec->uses_psids = 1;
+
+		/*
+		 * TBD: need to correctly label mountpoint with persistent
+		 * label at this point (currently vnode is unavailable)
+		 */
+
+		break;
+	case SECURITY_FS_USE_TRANS:
+		/* Transition SIDs are used for pseudo filesystems like
+		   devpts and tmpfs where you want the SID to be derived
+		   from the SID of the creating process and the SID of
+		   the filesystem. */
+		sbsec->uses_trans = 1;
+		break;
+	case SECURITY_FS_USE_TASK:
+		/* Task SIDs are used for pseudo filesystems like pipefs
+		   and sockfs where you want the objects to be labeled
+		   with the SID of the creating process. */
+		sbsec->uses_task = 1;
+		break;
+	case SECURITY_FS_USE_GENFS:
+		/* genfs_contexts handles everything else, like devfs,
+		   usbdevfs, driverfs, and portions of proc. */
+		sbsec->uses_genfs = 1;
+		break;
+	case SECURITY_FS_USE_NONE:
+		/* No labeling support configured for this filesystem type.
+		   Don't appear to require labeling for binfmt_misc, bdev,
+		   or rootfs. */
+		break;
+	default:
+		printf("%s:  security_fs_use(%s) returned unrecognized "
+		    "behavior %d\n", __FUNCTION__, mp->mnt_vfc->vfc_name,
+		    behavior);
+		behavior = SECURITY_FS_USE_NONE;
+		break;
+	}
+
+	if (mount_arg_label) {
+		mntsec = SLOT(mount_arg_label);
+		sbsec->sid = mntsec->sid;
+	}
+}
+
+/*
+ * Initialize the SEBSD security server after the root partition has
+ * been mounted; policy is located on root partition.
+ */
+static void
+sebsd_create_root_mount(struct ucred *cred, struct mount *mp,
+    struct label *mntlabel, struct label *fslabel)
+{
+	struct vnode *vp, *nvp;
+
+	/*
+	 * Go through all open vnodes and reload their labels.
+	 */
+	mtx_lock(&mntvnode_mtx);
+	vp = TAILQ_FIRST(&mp->mnt_nvnodelist);
+	do {
+		nvp = TAILQ_NEXT(vp, v_nmntvnodes);
+		VI_LOCK(vp);
+		mtx_unlock(&mntvnode_mtx);
+		vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread);
+		(void)sebsd_associate_vnode_extattr(mp, fslabel, vp,
+		    &vp->v_label);
+		VOP_UNLOCK(vp, 0, curthread);
+		mtx_lock(&mntvnode_mtx);
+		vp = nvp;
+	} while (vp != NULL);
+	mtx_unlock(&mntvnode_mtx);
+}
+
+static int
+sebsd_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+    struct label *fslabel, struct vnode *parent, struct label *parentlabel,
+    struct vnode *child, struct label *childlabel, struct componentname *cnp)
+{
+	struct vnode_security_struct *dir, *vsec;
+	struct task_security_struct *task;
+	security_context_t context;
+	u_int32_t context_len;
+	security_id_t newsid;
+	int error;
+	int tclass;
+
+ 	task = SLOT(&cred->cr_label);
+	dir = SLOT(parentlabel);
+	vsec = SLOT(childlabel);
+	tclass = vnode_type_to_security_class (child->v_type);
+
+	error = security_transition_sid(task->sid, dir->sid, tclass,
+					&newsid);
+	if (error)
+		return (error);
+
+	vsec->sid = newsid;
+	vsec->task_sid = task->sid;
+	vsec->sclass = tclass;
+
+	/* store label in vnode */
+	error = security_sid_to_context(vsec->sid, &context,
+					&context_len);
+	if (error)
+		return (error);
+
+	error = vn_extattr_set(child, IO_NODELOCKED,
+			       SEBSD_MAC_EXTATTR_NAMESPACE,
+			       SEBSD_MAC_EXTATTR_NAME,
+			       context_len, context, curthread);
+
+	security_free_context(context);
+	return (error);
+}
+
+static int
+sebsd_check_cap (struct ucred *cred, cap_value_t capv)
+{
+  return cred_has_capability (cred, capv);
+}
+
+/*
+ * SEBSD does not support the relabeling of processes without
+ * transitioning.
+ */
+static int
+sebsd_check_cred_relabel(struct ucred *cred, struct label *newlabel)
+{
+	struct task_security_struct *nsec, *tsec;
+
+	nsec = SLOT(newlabel);
+	tsec = SLOT(&cred->cr_label);
+	if (nsec != NULL && nsec->sid != tsec->sid)
+		return EPERM;
+	return 0;
+}
+
+static int
+sebsd_check_mount (struct ucred *cred, struct vnode *vp, struct label *vl,
+    const char *vfc_name, struct label *mntlabel)
+{
+	int rc;
+	security_id_t sid;
+	int behavior;
+	struct vnode_security_struct *vsec;
+	struct task_security_struct  *task;
+	struct mount_security_struct *sbsec;
+
+	vsec = SLOT(vl);
+	task = SLOT(&cred->cr_label);
+
+	rc = vnode_has_perm (cred, vp, FILE__MOUNTON, NULL);
+	if (rc)
+		return rc;
+
+	if (mntlabel) {
+		sbsec = SLOT(mntlabel);
+		sid = sbsec->sid;
+
+		rc = avc_has_perm_ref_audit (task->sid, sid, SECCLASS_FILE,
+		    COMMON_FILE__RELABELTO, NULL, NULL);
+		if (rc)
+			return rc;
+	}
+	else {
+		rc = security_fs_use (vfc_name, &behavior, &sid);
+		if (rc)
+			return rc;

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310110203.h9B23v9r049170>