PERFORCE change 107187 for review

Todd Miller millert at FreeBSD.org
Tue Oct 3 08:17:28 PDT 2006


http://perforce.freebsd.org/chv.cgi?CH=107187

Change 107187 by millert at millert_macbook on 2006/10/03 15:16:58

	Add iokit access control driver and corresponding MAC entrypoint
	Panic if audit cannot be initialized
	Export mac_vnop_removexattr to kexts
	Better color policy

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/darwin/Makefile#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControl.xcode/project.pbxproj#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlFireWire.cpp#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlFireWire.h#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlUSB.cpp#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlUSB.h#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/English.lproj/InfoPlist.strings#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/Info.plist#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/Makefile#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/README#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/Makefile#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_audit.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/vnode.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_xattr.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/config/MACFramework.exports#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOCatalogue.cpp#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOService.cpp#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/libsa/kext.cpp#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac.h#8 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_base.c#13 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#10 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_vfs_subr.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/Makefile#3 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/color/color_util.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.h#2 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/device_access/Makefile#1 add
.. //depot/projects/trustedbsd/sedarwin8/policies/device_access/mac_device_access.c#1 add

Differences ...

==== //depot/projects/trustedbsd/sedarwin8/darwin/Makefile#3 (text+ko) ====

@@ -8,6 +8,7 @@
 	$(MAKE) -C cctools
 	$(MAKE) -C kext_tools
 	$(MAKE) -C $(XNU)
+	$(MAKE) -C drivers
 	$(MAKE) -C bootstrap_cmds
 	$(MAKE) -C libmac
 	$(MAKE) -C mac_cmds
@@ -28,6 +29,7 @@
 		$(DESTDIR)/$(SYSTEM_PLUGINS)/
 	install -m 644 $(XNU)/BUILD/dst/mach_kernel $(DESTDIR)/
 	tar -C $(XNU)/BUILD/dst -cf - usr/include | tar -C $(DESTDIR) -xf -
+	$(MAKE) -C drivers DSTROOT=$(DESTDIR) install
 	$(MAKE) -C libmac install
 	$(MAKE) -C mac_cmds install
 	$(MAKE) -C osx_cmds install
@@ -47,6 +49,7 @@
 	$(MAKE) -C bootstrap_cmds clean
 	$(MAKE) -C cctools clean
 	$(MAKE) -C kext_tools clean
+	$(MAKE) -C drivers clean
 	$(MAKE) -C libmac clean
 	$(MAKE) -C mac_cmds clean
 	$(MAKE) -C osx_cmds clean

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_audit.c#5 (text+ko) ====

@@ -671,9 +671,8 @@
 	 * size as the system call table.
 	 */
 	if (nsys_au_event != nsysent) {
-		printf("Security auditing service initialization failed, ");
-		printf("audit event table doesn't match syscall table.\n");
-		return;
+		panic("Security auditing service initialization failed, "
+		      "audit event table doesn't match syscall table.");
 	}
 
 	printf("Security auditing service present\n");

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/vnode.h#3 (text+ko) ====

@@ -645,6 +645,8 @@
 int default_setxattr(vnode_t vp, const char *name, uio_t uio,
 		     int options, vfs_context_t context);
 
+int default_removexattr(vnode_t vp, const char *name, int options,
+			vfs_context_t context);
 __END_DECLS
 
 #endif /* KERNEL */

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_xattr.c#5 (text+ko) ====

@@ -53,7 +53,6 @@
 /*
  * Default xattr support routines.
  */
-static int default_removexattr(vnode_t vp, const char *name, int options, vfs_context_t context);
 
 static int default_listxattr(vnode_t vp, uio_t uio, size_t *size, int options,
                              vfs_context_t context);
@@ -989,7 +988,7 @@
 /*
  * Remove an extended attribute.
  */
-static int
+int
 default_removexattr(vnode_t vp, const char *name, __unused int options, vfs_context_t context)
 {
 	vnode_t xvp = NULL;

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/config/MACFramework.exports#5 (text+ko) ====

@@ -5,6 +5,7 @@
 
 _mac_vnop_getxattr
 _mac_vnop_setxattr
+_mac_vnop_removexattr
 
 _kau_will_audit
 _mac_audit_text
@@ -35,3 +36,8 @@
 _mac_zfree
 
 _mac_find_module_data
+
+_mac_iokit_check_device_allowed
+
+# This should really go in IOKit.exports.
+__Z13osdict_encodeP12OSDictionary

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOCatalogue.cpp#2 (text+ko) ====

@@ -123,14 +123,12 @@
 extern "C" kern_return_t kmod_release(kmod_t id);
 
 /*********************************************************************
-* This function takes a plist and looks for an OSModuleData dictionary.
-* If it is found, an encoded copy is returned.
+* This function takes an OSDictionary and returns a struct mac_module_data
+* list.
 *********************************************************************/
-kmod_args_t
-get_module_data(OSDictionary * kextPlist, mach_msg_type_number_t * datalen)
+struct mac_module_data *
+osdict_encode(OSDictionary *dict)
 {
-
-    OSDictionary * kextModuleData = 0;      // don't release
     const OSMetaClass * typeID;	            // don't release
     OSString * key = NULL;                  // don't release
     OSCollectionIterator * keyIterator = 0; // must release
@@ -138,16 +136,11 @@
     struct mac_module_data_element * element;
     unsigned int strtabsize = 0;
     unsigned int nkeys = 0;
+    unsigned int datalen;
     char * strtab = 0;
     vm_offset_t data_addr;
-    vm_map_copy_t copy = 0;
 
-    kextModuleData = OSDynamicCast(OSDictionary,
-	kextPlist->getObject("OSModuleData"));
-    if (!kextModuleData)
-        goto finish;
-
-    keyIterator = OSCollectionIterator::withCollection(kextModuleData);
+    keyIterator = OSCollectionIterator::withCollection(dict);
     if (!keyIterator)
         goto finish;
 
@@ -155,7 +148,7 @@
     while ( (key = OSDynamicCast(OSString, keyIterator->getNextObject())) ) {
 
 	// Get the key's value and determine its type
-        OSObject * value = kextModuleData->getObject(key);
+        OSObject * value = dict->getObject(key);
         if (!value)
             continue;
 
@@ -183,12 +176,12 @@
     /*
      * Allocate and fill in the module data structures.
      */
-    *datalen = sizeof(struct mac_module_data) +
+    datalen = sizeof(struct mac_module_data) +
 	sizeof(mac_module_data_element) * (nkeys - 1) + strtabsize;
-    if (kmem_alloc(kernel_map, &data_addr, *datalen) != KERN_SUCCESS)
+    if (kmem_alloc(kernel_map, &data_addr, datalen) != KERN_SUCCESS)
 	goto finish;
     module_data = (mac_module_data *)data_addr;
-    module_data->size = *datalen;
+    module_data->size = datalen;
     module_data->count = nkeys;
     strtab = (char *)&module_data->data[nkeys];
 
@@ -197,7 +190,7 @@
     while ( (key = OSDynamicCast(OSString, keyIterator->getNextObject())) ) {
 
 	// Get the key's value and determine its type
-        OSObject * value = kextModuleData->getObject(key);
+        OSObject * value = dict->getObject(key);
         if (!value)
             continue;
 
@@ -239,18 +232,41 @@
 	strtab += element->key_size + element->value_size;
 	element++;
     }
+finish:
+    if (keyIterator)
+	keyIterator->release();
+    return(module_data);
+}
+
+/*********************************************************************
+* This function takes a plist and looks for an OSModuleData dictionary.
+* If it is found, an encoded copy is returned.
+*********************************************************************/
+kmod_args_t
+get_module_data(OSDictionary * kextPlist, mach_msg_type_number_t * datalen)
+{
+
+    OSDictionary * kextModuleData = 0;      // don't release
+    struct mac_module_data * module_data = 0;
+    vm_map_copy_t copy = 0;
 
+    kextModuleData = OSDynamicCast(OSDictionary,
+	kextPlist->getObject("OSModuleData"));
+    if (!kextModuleData)
+        goto finish;
+
+    module_data = osdict_encode(kextModuleData);
+    if (!module_data)
+        goto finish;
+    *datalen = module_data->size;
     /*
      * Make a CoW copy of data and free the original.  The copy is
      * consumed by a call to vm_map_copyout() in kmod_start_or_stop().
      */
-    vm_map_copyin(kernel_map, (vm_offset_t)data_addr, *datalen, FALSE, &copy);
-    kmem_free(kernel_map, data_addr, *datalen);
+    vm_map_copyin(kernel_map, (vm_offset_t)module_data, *datalen, FALSE, &copy);
+    kmem_free(kernel_map, (vm_offset_t)module_data, *datalen);
 
 finish:
-    if (keyIterator)
-	keyIterator->release();
-
     return (kmod_args_t)copy;
 }
 
@@ -1427,4 +1443,3 @@
 
     IOLockUnlock(gIOKLDLock);
 }
-

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOService.cpp#2 (text+ko) ====

@@ -2320,6 +2320,8 @@
     OSObject 		*	nextMatch = 0;
     bool			started;
     bool			needReloc = false;
+    OSBoolean		*	isSandbox = 0;
+    bool			useSandbox = false;
 #if IOMATCHDEBUG
     SInt64			debugFlags;
 #endif
@@ -2428,6 +2430,8 @@
                 if( !symbol)
                     continue;
     
+                IOLog("%s alloc (symbol %p props %p)\n", symbol->getCStringNoCopy(), symbol, props);
+
                 // alloc the driver instance
                 inst = (IOService *) OSMetaClass::allocClassWithName( symbol);
     
@@ -2454,7 +2458,10 @@
                 if( 0 == category)
                     category = gIODefaultMatchCategoryKey;
                 inst->setProperty( gIOMatchCategoryKey, (OSObject *) category );
-    
+
+		isSandbox = OSDynamicCast(OSBoolean,
+                            props->getObject("IOKitForceMatch"));
+
                 // attach driver instance
                 if( !(inst->attach( this )))
                         continue;
@@ -2471,6 +2478,19 @@
     
                 newInst = inst->probe( this, &score );
                 inst->detach( this );
+		/*
+		 * If this is the Sandbox driver and it matched, this is a
+		 * disallowed device; toss any drivers that were already
+		 * matched.
+		 */
+		if (isSandbox && isSandbox->isTrue() && newInst != 0) {
+		    if (startDict != 0) {
+			startDict->flushCollection();
+			startDict->release();
+			startDict = 0;
+		    }
+		    useSandbox = true;
+		}
                 if( 0 == newInst) {
 #if IOMATCHDEBUG
                     if( debugFlags & kIOLogProbe)
@@ -2509,6 +2529,11 @@
             props->release();
             if( inst)
                 inst->release();
+	    /*
+	     * If we're forcing the sandbox, drop out of the loop.
+	     */
+	    if (isSandbox && isSandbox->isTrue() && useSandbox)
+		    break;
         }
         familyMatches->release();
         familyMatches = 0;

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/libsa/kext.cpp#2 (text+ko) ====

@@ -77,6 +77,8 @@
 extern kmod_args_t
 get_module_data(OSDictionary * kextPlist, mach_msg_type_number_t * datalen);
 
+extern struct mac_module_data *osdict_encode(OSDictionary *dict);
+
 #define DEBUG
 #ifdef DEBUG
 #define LOG_DELAY(x)    IODelay((x) * 1000000)

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#2 (text+ko) ====

@@ -23,3 +23,4 @@
 security/mac_socket.c					optional mac
 security/mac_net.c					optional mac
 security/mac_pipe.c					optional mac
+security/mac_iokit.c					optional mac

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac.h#8 (text+ko) ====

@@ -67,6 +67,12 @@
 
 typedef struct mac	*mac_t;
 
+/*
+ * Device types for mac_iokit_check_device_allowed()
+ */
+#define MAC_DEVICE_USB		0
+#define MAC_DEVICE_FIREWIRE	1
+
 #ifndef KERNEL
 /*
  * Location of the userland MAC framework configuration file.  mac.conf
@@ -107,6 +113,11 @@
 int	 mac_set_proc(const mac_t _label);
 int	 mac_syscall(const char *_policyname, int _call, void *_arg);
 int	 mac_to_text(mac_t mac, char **_text);
+/*
+ * I/O Kit device access control.
+ * Note that this routine is called from a C++ I/O Kit driver.
+ */
+int	mac_iokit_check_device_allowed(int devtype, struct module_data *mdata);
 __END_DECLS
 #endif
 

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_base.c#13 (text+ko) ====

@@ -1947,15 +1947,22 @@
 }
 
 int
-mac_vnop_setxattr (struct vnode *vp, const char *name, char *buf, size_t len)
+mac_vnop_setxattr(struct vnode *vp, const char *name, char *buf, size_t len)
+{
+
+	return (ENOENT);
+}
+
+int
+mac_vnop_getxattr(struct vnode *vp, const char *name, char *buf, size_t len,
+    size_t *attrlen)
 {
 
 	return (ENOENT);
 }
 
 int
-mac_vnop_getxattr (struct vnode *vp, const char *name, char *buf, size_t len,
-                   size_t *attrlen)
+mac_vnop_removexattr(struct vnode *vp, const char *name)
 {
 
 	return (ENOENT);

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#10 (text+ko) ====

@@ -4924,8 +4924,33 @@
 	int error,
 	int retval
 );
+
+/**
+  @brief Device hardware access control
+  @param devtype Type of device connected
+  @param properties XML-formatted property list
+  @param proplen Length of the property list
+
+  This is the MAC Framework device access control, which is called by the I/O
+  Kit when a new device is connected to the system to determine whether that
+  device should be trusted.  A list of properties associated with the device
+  is passed as an XML-formatted string.  The routine should examine these
+  properties to determine the trustworthiness of the device.  A return value
+  of EPERM forces the device to be claimed by a special device driver that
+  will prevent its operation.
+
+  @warning This is an experimental interface and may change in the future.
+
+  @return Return EPERM to indicate that the device is untrusted and should
+  not be allowed to operate.  Return zero to indicate that the device is
+  trusted and should be allowed to operate normally.
+
+*/
+typedef int mpo_iokit_check_device_allowed_t(
+	int devtype,
+	struct mac_module_data *mdata
+);
 /*@}*/
-
 /*!
   \struct mac_policy_ops
 */
@@ -5232,6 +5257,7 @@
 	mpo_pipe_check_select_t			*mpo_pipe_check_select;
 	mpo_pipe_check_stat_t			*mpo_pipe_check_stat;
 	mpo_pipe_check_write_t			*mpo_pipe_check_write;
+	mpo_iokit_check_device_allowed_t	*mpo_iokit_check_device_allowed;
 };
 
 /**
@@ -5309,6 +5335,7 @@
 int	mac_vnop_setxattr(struct vnode *, const char *, char *, size_t);
 int	mac_vnop_getxattr(struct vnode *, const char *, char *, size_t,
 			  size_t *);
+int	mac_vnop_removexattr(struct vnode *, const char *);
 
 /*
  * Arbitrary limit on how much data will be logged by the audit

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_vfs_subr.c#3 (text+ko) ====

@@ -124,3 +124,19 @@
 
 	return (error);
 }
+
+int
+mac_vnop_removexattr (struct vnode *vp, const char *name)
+{
+	struct vfs_context context;
+	int error;
+
+	context.vc_proc = current_proc();
+	context.vc_ucred = kauth_cred_get(); 
+
+	error = VNOP_REMOVEXATTR(vp, name, 0, &context);
+	if (error == ENOTSUP || error == EPERM)
+		error = default_removexattr(vp, name, 0, &context);
+
+	return (error);
+}

==== //depot/projects/trustedbsd/sedarwin8/policies/Makefile#3 (text+ko) ====

@@ -1,5 +1,6 @@
-SUBDIR=		basetest color console count fwinteg ipctrace mls none \
-		readonly stacktrace stub test vanity xattr extattr_test
+SUBDIR=		basetest color console count device_access extattr_test \
+		fwinteg ipctrace mls multilabel none readonly stacktrace \
+		stub test vanity xattr
 SUBDIR+=	sedarwin
 
 include mk/subdir.mk

==== //depot/projects/trustedbsd/sedarwin8/policies/color/color_util.c#2 (text+ko) ====

@@ -96,14 +96,13 @@
 		LIST_REMOVE(mc, list);
 		free_count--;
 		mc->refs = 0;
-		mc->valid = 0;
 	}
 
-	mc->refs++;
+	mc->refs = 1;
 	used_count++;
 	mc->color = &colors[0];
 	LIST_INSERT_HEAD(&mc_list_used, mc, list);
-//	printf("mc_alloc, mc=%p, refs=%d\n", mc, mc->refs);
+	MCPRINTF("%s:: mc=%p, refs=%d\n", __func__, mc, mc->refs);
 
 	return (mc);
 }
@@ -114,7 +113,7 @@
 
 	if (mc == NULL)
 		return;
-//	printf("mc_free, mc=%p, refs=%d\n", mc, mc->refs);
+	MCPRINTF("%s:: mc=%p, refs=%d\n", __func__, mc, mc->refs);
 	LIST_REMOVE(mc, list);
 	used_count--;
 
@@ -146,7 +145,10 @@
 	if (mc == NULL)
 		return;
 
-	if (--mc->refs <= 0)
+	mc->refs--;
+	MCPRINTF("%s:: mc=%p, refs=%d\n", __func__, mc, mc->refs);
+
+	if (mc->refs <= 0)
 		mc_free(mc);
 
 	co_setreflabel(label, NULL);
@@ -205,15 +207,17 @@
 	if (SLOTREF(dst) != NULL) {
 		/* Already has a reference. */
 		if (SLOTREF(dst) == mc) {
-//			printf("co_reference_label: already has matching reference\n");
+			MCPRINTF("%s:: already has matching reference\n",
+			    __func__);
 			return;
 		} else {
-//			printf("co_reference_label: already has a reference\n");
+			MCPRINTF("%s:: already has a reference\n", __func__);
 		}
 		co_destroy_reflabel(dst);
 	}
-	printf("co_reference_label: copying reference, mc=%p, refs=%d\n", mc, mc->refs);
 	mc->refs++;
+	MCPRINTF("%s:: copying reference, mc=%p, refs=%d\n", __func__, mc,
+	    mc->refs);
 	co_setreflabel(dst, mc);
 
 	return;
@@ -234,6 +238,33 @@
 }
 
 
+int
+co_maybe_promote_process(struct ucred *subject, struct label *object)
+{
+	struct color *filecolor, *credcolor;
+
+	filecolor = co_getlabel(object);
+	credcolor = co_getreflabel(subject->cr_label)->color;
+
+	/* 
+	 * If the file doesn't have a label or they are the same
+	 */
+	if ((filecolor == NULL) || (filecolor == credcolor))
+		return (0);
+	
+	MCPRINTF("%s:: checking file label %s(%d) with cred %s(%d)\n",
+	    __func__, filecolor->name, filecolor->level,
+	    credcolor->name, credcolor->level);
+
+	if (filecolor->level > credcolor->level) {
+		printf("%s:: promoting label from %s to %s\n",
+		    __func__, credcolor->name, filecolor->name);
+		co_getreflabel(subject->cr_label)->color = filecolor;
+	}
+
+	return (0);
+}
+
 void
 color_policy_init(struct mac_policy_conf *conf)
 {

==== //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.c#5 (text+ko) ====

@@ -24,6 +24,28 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * The MAC Color policy.
+ * 
+ * This policy demonstrates the potential of using login context
+ * labels to share privilege amongst a group of processes.  It also
+ * demonstrates the use of floating labels.
+ * 
+ * The policy has a small number of "rules": 
+ *     1) All processes have a color.  Files may optionally have a color.
+ *     2) Colors are ranked low to high by their position in the
+ *         spectrum (red to violet).
+ *     3) A subject takes on the color of the highest object it is accessing.
+ *     4) Objects created by a subject will have the higher of the color
+ *        of the subject at the time of creation or the enclosing directory.
+ *     5) Objects created will only have a label if the parent directory
+ *        has a label.
+ *
+ * Note that this is an example policy, not all entry points are
+ * imlemented and not all subject access considered.
+ */
+
+
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -33,6 +55,7 @@
 #include <sys/sbuf.h>
 #include <sys/systm.h>
 #include <sys/vnode.h>
+#include <sys/vnode_internal.h>		/* struct vfs_context */
 #include <sys/mman.h>
 #include <sys/fcntl.h>
 #include <sys/kauth.h>
@@ -46,7 +69,7 @@
 static const char *labelnamespaces[MAC_COLOR_LABEL_COUNT] = 
 	{ MAC_COLOR_POLICY_NAME };
 
-static int color_slot;			/* Per-policy label storage */
+int color_slot;			/* Per-policy label storage */
 
 static mac_policy_handle_t mac_color_handle;
 
@@ -77,7 +100,13 @@
 {
 	struct color *color;
 
+	if (strncmp(string, "unlabeled", 9) == 0) {
+		co_setreflabel(label, NULL);
+		return (0);
+	}
+
 	co_setlabelstring(label, string);
+
 	color = co_getlabel(label);
 	if (color == NULL) {
 		printf("%s: No matching color for %s\n", __func__, string);
@@ -126,7 +155,6 @@
 color_cred_create(struct ucred *parent_cred, struct ucred *child_cred) 
 {
 
-//	co_copylabel(parent_cred->cr_label, child_cred->cr_label);
 	co_reference_label(parent_cred->cr_label, child_cred->cr_label);
 }
 
@@ -134,38 +162,52 @@
 color_create_kernel_proc(struct ucred *cred)
 {
 
-	//co_setlabel(cred->cr_label, &colors[0]);
+	/* Nothing to do here */
 }
 
-/* ================================================================= *
- * login context entry points
- * ================================================================= */
+static int
+color_cred_check_setlabel(struct ucred *cred, struct label *newlabel) 
+{
 
-#if 0
-static void
-color_lctx_init_label(struct label *label)
-{
+	return (EPERM);
 }
 
-static void
-color_lctx_destroy_label(struct label *label)
+static int
+color_proc_check_signal(struct ucred *cred, struct proc *proc, int signum)
 {
+
+	struct color *subjectcolor, *objectcolor;
+
+	subjectcolor = co_getreflabel(cred->cr_label)->color;
+	objectcolor  = co_getreflabel(proc_ucred(proc)->cr_label)->color;
+
+	if (objectcolor->level > subjectcolor->level) {
+		printf("%s:: promoting label from %s to %s\n",
+		    __func__, subjectcolor->name, objectcolor->name);
+		co_getreflabel(cred->cr_label)->color = objectcolor;
+	}
+
+	return (0);
 }
-#endif
+
+/* ================================================================= *
+ * login context entry points
+ * ================================================================= */
 
 static void
 color_proc_create_lctx(struct proc *p, struct lctx *l)
 {
 
-//	co_copylabel(proc_ucred(p)->cr_label, l->lc_label);
-//	co_reference_label(proc_ucred(p)->cr_label, l->lc_label);
-	printf("create_lctx:: process(%s) color %s(%d) creating lctx (which was color %s(%d))\n",
-	       p->p_comm,
-	       co_getreflabel(proc_ucred(p)->cr_label)->color->name,
-	       co_getreflabel(proc_ucred(p)->cr_label)->refs,
-	       co_getreflabel(l->lc_label)->color->name,
-	       co_getreflabel(l->lc_label)->refs);
-	co_getreflabel(l->lc_label)->color = co_getreflabel(proc_ucred(p)->cr_label)->color;
+	printf("%s: process(%s) color %s(%d) create lctx (was color %s(%d))\n",
+	    __func__, p->p_comm,
+	    co_getreflabel(proc_ucred(p)->cr_label)->color->name,
+	    co_getreflabel(proc_ucred(p)->cr_label)->refs,
+	    co_getreflabel(l->lc_label)->color->name,
+	    co_getreflabel(l->lc_label)->refs);
+
+	/* copy process label to lctx */
+	co_getreflabel(l->lc_label)->color = 
+	    co_getreflabel(proc_ucred(p)->cr_label)->color;
 }
 
 static void
@@ -173,37 +215,56 @@
 {
 
 	co_reference_label(l->lc_label, proc_ucred(p)->cr_label);
-	printf("join_lctx:: process(%s) color %s to join lctx color %s\n",
-	       p->p_comm,
-	       co_getreflabel(p->p_ucred->cr_label)->color->name,
-	       co_getreflabel(l->lc_label)->color->name);
+	MCPRINTF("%s:: process(%s) pid(%d) '%s' to join lctx '%s'\n",
+	    __func__, p->p_comm, p->p_pid,
+	    co_getreflabel(p->p_ucred->cr_label)->color->name,
+	    co_getreflabel(l->lc_label)->color->name);
 }
 
 static void
 color_proc_leave_lctx(struct proc *p, struct lctx *l)
 {
 
-	printf("leave_lctx:: process(%s) color %s to join lctx color %s\n",
-	       p->p_comm,
-	       co_getreflabel(p->p_ucred->cr_label)->color->name,
-	       co_getreflabel(l->lc_label)->color->name);
+	MCPRINTF("%s:: process(%s) pid(%d) '%s' to leave lctx '%s'\n",
+	    __func__, p->p_comm, p->p_pid,
+	    co_getreflabel(p->p_ucred->cr_label)->color->name,
+	    co_getreflabel(l->lc_label)->color->name);
 }
 
 static void
 color_lctx_setlabel(struct lctx *l, struct label *newlabel)
 {
 
-	printf("lctx_setlabel:: newlabel color %s for lctx color %s\n",
-	       co_getreflabel(newlabel)->color->name,
-	       co_getreflabel(l->lc_label)->color->name);
+	printf("%s:: newlabel color %s for lctx color %s\n",
+	    __func__, co_getreflabel(newlabel)->color->name,
+	    co_getreflabel(l->lc_label)->color->name);
 }
 
 
 /* ================================================================= *
  * vnode entry points
  * ================================================================= */
+static void
+color_mount_create(struct ucred *cred, struct mount *mp,
+    struct label *mntlabel)
+{
+	struct color *credcolor;
+
+	credcolor = co_getreflabel(cred->cr_label)->color;
+	co_setlabel(mntlabel, credcolor);
+}
+
 static int
-color_vnode_associate_extattr(struct mount *mp, struct label *fslabel,
+color_mount_check_setlabel(struct ucred *cred, struct mount *mp,
+    struct label *mntlabel) 
+{
+
+	return (EPERM);
+}
+
+
+static int
+color_vnode_associate_extattr(struct mount *mp, struct label *mntlabel,
     struct vnode *vp, struct label *vlabel)
 {
 	int error;
@@ -214,6 +275,7 @@
 	error = mac_vnop_getxattr(vp, MAC_COLOR_XATTR_NAME, buf,
 	    sizeof(buf), &buflen);
 
+	/* If there's no attribute, the label is NULL */
 	if (error == ENOATTR || error == EOPNOTSUPP)
 		return (0);
 
@@ -227,11 +289,20 @@
 }
 
 static void
-color_vnode_associate_singlelabel(struct mount *mp, struct label *fslabel,
+color_devfs_vnode_associate(struct mount *mp, struct label *mntlabel,
+    struct devnode *de, struct label *delabel, struct vnode *vp,
+    struct label *vlabel)
+{
+
+	co_copylabel(mntlabel, vlabel);
+}
+
+static void
+color_vnode_associate_singlelabel(struct mount *mp, struct label *mntlabel,
     struct vnode *vp, struct label *vlabel)
 {
 
-	co_setlabel(vlabel, NULL);
+	co_copylabel(mntlabel, vlabel);
 }
 
 static void
@@ -251,30 +322,39 @@
 
 static int
 color_vnode_create_extattr(struct ucred *cred, struct mount *mp,
-    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
+    struct label *mntlabel, struct vnode *dvp, struct label *dlabel,
     struct vnode *vp, struct label *vlabel, struct componentname *cnp)
 {
-	int error;
-	struct color *color;
+	int error = 0;
+	struct color *dircolor, *credcolor, *newcolor;
 
-	/* For now, just inherit the parent directory label */
-	color = co_getlabel(dlabel);
-	if (color == NULL)
-		return (0);
+	dircolor = co_getlabel(dlabel);
+	credcolor = co_getreflabel(cred->cr_label)->color;
 
-	error = mac_vnop_setxattr(vp, MAC_COLOR_XATTR_NAME,
-	    color->name, sizeof(color->name));
+	/*
+	 * Process credentials always have labels, but files may not.
+	 * If the parent directory has no label, the new file will have
+	 * no label.  Otherwise, the new file gets the higher of the
+	 * parent label or the process label.
+	 */
+	if ((dircolor == NULL) || (dircolor->level > credcolor->level))
+		newcolor = dircolor;
+	else
+		newcolor = credcolor;
 
-	if (error)
-		co_setlabel(vlabel, NULL);
-	else
-		co_copylabel(dlabel, vlabel);
+	co_setlabel(vlabel, newcolor);
+	if (newcolor != NULL) {
+		error = mac_vnop_setxattr(vp, MAC_COLOR_XATTR_NAME,
+		    newcolor->name, sizeof(newcolor->name));
+		if (error)
+			printf("%s:: Couldn't set file label \n", __func__);
+	}
 
 	return (error);
 }
 
 static void
-color_vnode_update_extattr(struct mount *mp, struct label *fslabel,
+color_vnode_update_extattr(struct mount *mp, struct label *mntlabel,
     struct vnode *vp, struct label *vlabel, char *name)
 {
 	int error;
@@ -285,6 +365,7 @@
 	error = mac_vnop_getxattr(vp, MAC_COLOR_XATTR_NAME, buf,
 	    sizeof(buf), &buflen);
 
+	/* It's ok to have a NULL file label */
 	if (error)
 		return;
 
@@ -300,10 +381,11 @@
 {
 	int error;
 	struct color *color;
+	struct vfs_context context;
 
 	color = co_getlabel(intlabel);
 	if (color == NULL)
-		return (0);
+		return (mac_vnop_removexattr(vp, MAC_COLOR_XATTR_NAME));
 
 	error = mac_vnop_setxattr(vp, MAC_COLOR_XATTR_NAME,
 	    color->name, sizeof(color->name));
@@ -312,90 +394,357 @@
 }
 
 static int
+color_vnode_check_access(struct ucred *cred, struct vnode *vp,
+    struct label *label, int acc_mode)
+{
+
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
+    struct label *label)
+{
+
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
+    struct label *label) 
+{
+
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_create(struct ucred *cred, struct vnode *dvp,
+    struct label *label, struct componentname *cnp, struct vnode_attr *vap) 
+{
+
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
+    struct label *dlabel, struct vnode *vp, struct label *label,
+    struct componentname *cnp) 
+{
+
+	(void)co_maybe_promote_process(cred, dlabel);
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
+    struct label *label, const char *name) 
+{
+
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+
+color_vnode_check_exchangedata(struct ucred *cred, struct vnode *v1,
+    struct label *vl1, struct vnode *v2, struct label *vl2)
+{
+
+	(void)co_maybe_promote_process(cred, vl1);
+	return (co_maybe_promote_process(cred, vl2));
+}
+
+static int
+color_vnode_check_exec(struct ucred *cred, struct vnode *vp,
+    struct label *label, struct label *execlabel)
+{
+
+	if (execlabel != NULL)
+		(void)co_maybe_promote_process(cred, execlabel);
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_getattrlist(struct ucred *cred, struct vnode *vp,
+    struct label *label, struct attrlist *alist) 
+{
+
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
+    struct label *label, const char *name, struct uio *uio) 
+{
+
+	return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_kqfilter(struct ucred *cred, struct ucred *file_cred,
+    struct knote *kn, struct vnode *vp, struct label *label) 
+{

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


More information about the trustedbsd-cvs mailing list