PERFORCE change 78641 for review

Andrew Reisse areisse at FreeBSD.org
Thu Jun 16 18:24:43 GMT 2005


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

Change 78641 by areisse at areisse_ibook on 2005/06/16 18:24:09

	Many label handle related fixes:
	-Use the zone allocator and properly free the ports.
	-Locking fixes.
	-Move the security.defs calls to a new file, kern/security.c.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/conf/files#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_init.c#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.c#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.h#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.c#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.h#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/mach_port.c#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/ipc_kobject.c#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/security.c#1 add
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.c#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.h#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/mach/security.defs#2 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/conf/files#2 (text+ko) ====

@@ -168,6 +168,7 @@
 osfmk/kern/processor.c		standard
 osfmk/kern/queue.c			standard
 osfmk/kern/sched_prim.c		standard
+osfmk/kern/security.c		standard
 osfmk/kern/sscanf.c			standard
 osfmk/kern/startup.c			standard
 osfmk/kern/sync_lock.c		standard

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_init.c#3 (text+ko) ====

@@ -165,6 +165,12 @@
 	/* make it exhaustible */
 	zone_change(ipc_object_zones[IOT_PORT_SET], Z_EXHAUST, TRUE);
 
+	ipc_labelh_zone = 
+		zinit(sizeof(struct ipc_labelh),
+		      ipc_port_max * sizeof(struct ipc_labelh),
+		      sizeof(struct ipc_labelh),
+		      "label handles");
+
 	/* create special spaces */
 
 	kr = ipc_space_create_special(&ipc_space_kernel);

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.c#3 (text+ko) ====

@@ -4,6 +4,8 @@
 #include <ipc/ipc_labelh.h>
 #include <kern/ipc_kobject.h>
 
+zone_t ipc_labelh_zone;
+
 kern_return_t mac_label_new (ipc_space_t task, mach_port_name_t *name,
 			     vm_offset_t labelstr)
 {
@@ -21,7 +23,7 @@
 
   port = ipc_port_alloc_kernel();
 
-  lh = kalloc(sizeof(struct ipc_labelh));
+  lh = (ipc_labelh_t) zalloc(ipc_labelh_zone);
   io_lock_init(lh);
   lh->lh_port = port;
   lh->lh_type = 0;
@@ -44,7 +46,7 @@
 */
 ipc_labelh_t labelh_new ()
 {
-  ipc_labelh_t lh = (ipc_labelh_t) kalloc(sizeof(struct ipc_labelh));
+  ipc_labelh_t lh = (ipc_labelh_t) zalloc(ipc_labelh_zone);
   io_lock_init(lh);
   lh->lh_port = ipc_port_alloc_kernel();
   lh->lh_type = 0;
@@ -58,7 +60,7 @@
 
 ipc_labelh_t labelh_duplicate (ipc_labelh_t old)
 {
-  ipc_labelh_t lh = (ipc_labelh_t) kalloc(sizeof(struct ipc_labelh));
+  ipc_labelh_t lh = (ipc_labelh_t) zalloc(ipc_labelh_zone);
   io_lock_init(lh);
   lh->lh_port = ipc_port_alloc_kernel();
   lh->lh_type = 0;
@@ -93,7 +95,7 @@
   return lh;
 }
 
-void labelh_release (ipc_labelh_t lh)
+void labelh_release(ipc_labelh_t lh)
 {
   lh_lock(lh);
   lh_release(lh);
@@ -102,6 +104,7 @@
 
 void lh_free (ipc_labelh_t lh)
 {
-    ipc_object_release(lh->lh_port);
+    ipc_object_release(&lh->lh_port->ip_object);
     mac_destroy_port_label (&lh->lh_label);
+    zfree(ipc_labelh_zone, (vm_offset_t)lh);
 }

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.h#3 (text+ko) ====

@@ -32,6 +32,8 @@
 	(lh)->lh_references--;				\
 MACRO_END
 
+extern zone_t ipc_labelh_zone;
+
 #define lh_lock io_lock
 #define lh_unlock io_unlock
 

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.c#3 (text+ko) ====

@@ -995,6 +995,11 @@
  * that takes a security label as a parameter. In this case, we want
  * to use the label stored in the label handle and not the label on its
  * port.
+ *
+ * The port should be locked for this call. The lock protecting
+ * label handle contents should not be necessary, as they can only
+ * be modified when a label handle with one reference is a task label.
+ * User allocated label handles can never be modified.
  */
 
 struct label *io_getlabel (ipc_object_t objp)

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.h#3 (text+ko) ====

@@ -226,42 +226,15 @@
 	(io)->io_references--;						\
 MACRO_END
 
-/* There doesn't seem to be an established lock order for two
-   ipc_objects of the same type */
-extern inline void io_lock2 (ipc_object_t a, ipc_object_t b)
-{
-  if (a == b)
-    io_lock (a);
-  else if (a < b)
-    {
-      io_lock (a);
-      io_lock (b);
-    }
-  else
-    {
-      io_lock (b);
-      io_lock (a);
-    }
-}
+/*
+ * Retrieve a label for use in a kernel call that takes a security
+ * label as a parameter. If necessary, io_getlabel acquires internal
+ * (not io_lock) locks, and io_unlocklabel releases them.
+ */
 
-extern inline void io_unlock2 (ipc_object_t a, ipc_object_t b)
-{
-  if (a == b)
-    io_unlock (a);
-  else if (a < b)
-    {
-      io_unlock (b);
-      io_unlock (a);
-    }
-  else
-    {
-      io_unlock (a);
-      io_unlock (b);
-    }
-}
-
 struct label;
 extern struct label *io_getlabel (ipc_object_t obj);
+#define io_unlocklabel(obj) 
 
 /*
  * Exported interfaces

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/mach_port.c#3 (text+ko) ====

@@ -1792,6 +1792,7 @@
 
 	mac_externalize_port_label (l, policies, outlabel, 512, 0);
 
+	io_unlocklabel(entry->ie_object);
 	io_unlock (entry->ie_object);
 	return 0;
 }

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/ipc_kobject.c#2 (text+ko) ====

@@ -88,6 +88,7 @@
 #include <kern/misc_protos.h>
 #include <ipc/ipc_kmsg.h>
 #include <ipc/ipc_port.h>
+#include <ipc/ipc_labelh.h>
 #include <kern/counters.h>
 
 
@@ -515,6 +516,10 @@
 		host_notify_port_destroy(port);
 		break;
 
+	case IKOT_LABELH:
+		labelh_release(port->ip_kobject);
+		break;
+
 	default:
 		break;
 	}

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.c#3 (text+ko) ====

@@ -1756,6 +1756,31 @@
 	return (current_task_fast());
 }
 
+/*
+ * Protect 2 task labels against modification by adding a reference on
+ * both label handles. The locks do not actually have to be held while
+ * using the labels as only labels with one reference can be modified
+ * in place.
+ */
+
+void
+tasklabel_lock2(
+	task_t a,
+	task_t b)
+{
+	labelh_reference(a->label);
+	labelh_reference(b->label);
+}
+
+void
+tasklabel_unlock2(
+	task_t a,
+	task_t b)
+{
+	labelh_release(a->label);
+	labelh_release(b->label);
+}
+
 void mac_update_task_label (struct label *pl, struct task *t)
 {
   tasklabel_lock (t);
@@ -1776,160 +1801,3 @@
   tasklabel_unlock (pt);
 }
 
-kern_return_t
-mach_get_task_label_text(
-	task_t		t,
-	labelstr_t	policies,
-	labelstr_t	outl)
-{
-	tasklabel_lock (t);
-	mac_externalize_task_label (&t->maclabel, policies, outl, 512, 0);
-	tasklabel_unlock (t);
-  
-	return KERN_SUCCESS;
-}
-
-int mac_check_task_service_access (task_t self, task_t obj, const char * perm)
-{
-  tasklabel_lock2 (self, obj);
-
-  int rc = mac_check_service_access (&self->maclabel, &obj->maclabel, 
-				     "mach_task", perm);
-
-  tasklabel_unlock2 (self, obj);
-
-  return rc;
-}
-
-kern_return_t
-mac_check_named_access (ipc_space_t space, labelstr_t subj, labelstr_t obj,
-			labelstr_t serv, labelstr_t perm)
-{
-  struct label subjl, objl;
-
-  mac_init_task_label (&subjl);
-  int rc = mac_internalize_port_label (&subjl, subj);
-  if (rc)
-    {
-      mac_destroy_task_label (&subjl);
-      return KERN_INVALID_ARGUMENT;
-    }
-  mac_init_task_label (&objl);
-  rc = mac_internalize_port_label (&objl, obj);
-  if (rc)
-    {
-      mac_destroy_task_label (&subjl);
-      mac_destroy_task_label (&objl);
-      return KERN_INVALID_ARGUMENT;
-    }
-
-  rc = mac_check_service_access (&subjl, &objl, serv, perm);
-  mac_destroy_task_label (&subjl);
-  mac_destroy_task_label (&objl);
-  if (rc == /*EINVAL*/ 22)
-    return KERN_INVALID_ARGUMENT;
-  else if (rc != 0)
-    return KERN_NO_ACCESS;
-  else
-    return 0;
-}
-
-kern_return_t
-mac_check_name_port_access (ipc_space_t space, labelstr_t subj, mach_port_name_t obj,
-			    labelstr_t serv, labelstr_t perm)
-{
-  struct label  subjl;
-  ipc_entry_t   entry;
-  ipc_object_t  objp;
-  kern_return_t kr;
-  struct label  *objl;
-
-  if (space == IS_NULL || space->is_task == NULL)
-    return KERN_INVALID_TASK;
-
-  if (!MACH_PORT_VALID(obj))
-    return KERN_INVALID_NAME;
-
-  mac_init_task_label (&subjl);
-  int rc = mac_internalize_port_label (&subjl, subj);
-  if (rc)
-    {
-      mac_destroy_task_label (&subjl);
-      return KERN_INVALID_ARGUMENT;
-    }
-
-  kr = ipc_right_lookup_write(space, obj, &entry);
-  if (kr != KERN_SUCCESS)
-    {
-      mac_destroy_task_label (&subjl);
-      return kr;
-    }
-
-  objp = entry->ie_object;
-  io_lock (objp);
-  is_write_unlock (space);
-
-  objl = io_getlabel (objp);
-  if (objl == NULL) {
-    io_unlock (objp);
-    return KERN_INVALID_ARGUMENT;
-  }
-
-  rc = mac_check_service_access (&subjl, objl, serv, perm);
-  io_unlock (objp);
-
-  mac_destroy_task_label (&subjl);
-  if (rc == /*EINVAL*/ 22)
-    return KERN_INVALID_ARGUMENT;
-  else if (rc != 0)
-    return KERN_NO_ACCESS;
-  else
-    return 0;
-}
-
-kern_return_t
-mac_check_port_access (ipc_space_t space, mach_port_name_t sub, mach_port_name_t obj,
-		       labelstr_t serv, labelstr_t perm)
-{
-  ipc_entry_t    subi, obji;
-  ipc_object_t   subp, objp;
-  kern_return_t  kr;
-  struct label  *objl, *subl;
-  int            rc;
-
-  if (space == IS_NULL || space->is_task == NULL)
-    return KERN_INVALID_TASK;
-
-  if (!MACH_PORT_VALID(obj) || !MACH_PORT_VALID(sub))
-    return KERN_INVALID_NAME;
-
-  kr = ipc_right_lookup_two_write(space, obj, &obji, sub, &subi);
-  if (kr != KERN_SUCCESS)
-    return kr;
-
-  objp = obji->ie_object;
-  subp = subi->ie_object;
-  is_write_unlock (space);
-
-  io_lock2 (objp, subp);
-  objl = io_getlabel (objp);
-  if (objl == NULL)
-    goto errout;
-  subl = io_getlabel (subp);
-  if (subl == NULL)
-    goto errout;
-
-  rc = mac_check_service_access (subl, objl, serv, perm);
-  io_unlock2 (subp, objp);
-
-  if (rc == /*EINVAL*/ 22)
-    return KERN_INVALID_ARGUMENT;
-  else if (rc != 0)
-    return KERN_NO_ACCESS;
-  else
-    return 0;
-
- errout:
-  io_unlock2 (subp, objp);
-  return KERN_INVALID_ARGUMENT;
-}

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.h#3 (text+ko) ====

@@ -245,8 +245,8 @@
 #define tasklabel_lock(task) io_lock((task)->label)
 #define tasklabel_unlock(task) io_unlock((task)->label)
 
-#define tasklabel_lock2(a,b) /*io_lock2 ((a)->label, (b)->label)*/
-#define tasklabel_unlock2(a,b) /*io_unlock2 ((a)->label, (b)->label)*/
+extern void tasklabel_lock2(task_t a, task_t b);
+extern void tasklabel_unlock2(task_t a, task_t b);
 
 #endif
 

==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/mach/security.defs#2 (text+ko) ====

@@ -23,6 +23,12 @@
 			    policies  : labelstr_t;
 			    out label : labelstr_t);
 
+/*
+ * Relabel a port. This does not alter the user label data in a label
+ * handle, but changes the label that is used for access control on the
+ * port itself. That label cannot be retrieved (with the current interfaces).
+ */
+
 routine mach_set_port_label(task      : ipc_space_t;
 			    name      : mach_port_name_t;
 			    label     : labelstr_t);
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list