Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Feb 2004 07:20:07 -0800 (PST)
From:      Andrew Reisse <areisse@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 46537 for review
Message-ID:  <200402051520.i15FK7dh042372@repoman.freebsd.org>

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

Change 46537 by areisse@areisse_ibook on 2004/02/05 07:19:54

	Initial support for label handles that use the same namespace as ports.
	The label cannot be changed after creation, allowing them to be shared
	in the future. A new access control query, mac_check_port_access
	uses ports (or label handles) for both the subject and object.

Affected files ...

.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/conf/files#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_entry.h#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_init.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_labelh.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_labelh.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_object.c#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_object.h#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_right.c#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/mach_port.c#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/kern/task.c#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/mach/port.h#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/mach/security.defs#2 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/conf/files#3 (text+ko) ====

@@ -135,6 +135,7 @@
 osfmk/ipc/ipc_space.c			standard
 osfmk/ipc/ipc_splay.c			standard
 osfmk/ipc/ipc_table.c			standard
+osfmk/ipc/ipc_labelh.c			standard
 osfmk/ipc/mach_debug.c		standard
 osfmk/ipc/mach_msg.c			standard
 osfmk/ipc/mach_port.c			standard

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_entry.h#2 (text+ko) ====

@@ -114,7 +114,7 @@
 #define	IE_BITS_UREFS_MASK	0x0000ffff	/* 16 bits of user-reference */
 #define	IE_BITS_UREFS(bits)	((bits) & IE_BITS_UREFS_MASK)
 
-#define	IE_BITS_TYPE_MASK	0x001f0000	/* 5 bits of capability type */
+#define	IE_BITS_TYPE_MASK	0x003f0000	/* 6 bits of capability type */
 #define	IE_BITS_TYPE(bits)	((bits) & IE_BITS_TYPE_MASK)
 
 #define	IE_BITS_COLLISION	0x00800000	/* 1 bit for collisions */

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_init.c#2 (text+ko) ====

@@ -76,6 +76,7 @@
 #include <ipc/ipc_hash.h>
 #include <ipc/ipc_init.h>
 #include <mach/machine/ndr_def.h>   /* NDR_record */
+#include <ipc/ipc_labelh.h>
 
 vm_map_t ipc_kernel_map;
 vm_size_t ipc_kernel_map_size = 1024 * 1024;
@@ -153,6 +154,12 @@
 	/* make it exhaustible */
 	zone_change(ipc_object_zones[IOT_PORT_SET], Z_EXHAUST, TRUE);
 
+	ipc_object_zones[IOT_LABELH] =
+		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/sedarwin/apsl/xnu/osfmk/ipc/ipc_object.c#3 (text+ko) ====

@@ -72,6 +72,7 @@
 #include <ipc/ipc_right.h>
 #include <ipc/ipc_notify.h>
 #include <ipc/ipc_pset.h>
+#include <ipc/ipc_labelh.h>
 
 zone_t ipc_object_zones[IOT_NUMBER];
 
@@ -972,6 +973,19 @@
 	return kr;
 }
 
+struct label *io_getlabel (ipc_object_t objp)
+{
+  switch (io_otype (objp))
+    {
+    case IOT_PORT:
+      return &((ipc_port_t) objp)->ip_label;
+
+    case IOT_LABELH:
+      return &((ipc_labelh_t) objp)->lh_label;
+    }
+  return NULL;
+}
+
 #if	MACH_ASSERT
 /*
  *	Check whether the object is a port if so, free it.  But
@@ -992,7 +1006,11 @@
 
 #ifdef MAC
 		mac_destroy_port_label (&port->ip_label);
-#endif
+	}
+	else if (otype == IOT_LABELH) {
+	  ipc_labelh_t lh = (ipc_labelh_t) object;
+	  mac_destroy_port_label (&lh->lh_label);
+#endif	  
 	}
 	zfree(ipc_object_zones[otype], (vm_offset_t) object);
 }

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_object.h#2 (text+ko) ====

@@ -133,7 +133,8 @@
  */
 #define	IOT_PORT		0
 #define IOT_PORT_SET		1
-#define IOT_NUMBER		2		/* number of types used */
+#define IOT_LABELH              2 /* a label handle */
+#define IOT_NUMBER		3 /* number of types used */
 
 extern zone_t ipc_object_zones[IOT_NUMBER];
 
@@ -223,6 +224,43 @@
 	(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);
+    }
+}
+
+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);
+
 /*
  * Exported interfaces
  */

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/ipc_right.c#3 (text+ko) ====

@@ -551,6 +551,10 @@
 		break;
 	    }
 
+	    case MACH_PORT_TYPE_LABELH:
+	      ipc_object_release (entry->ie_object);
+	      break;
+
 	    case MACH_PORT_TYPE_SEND:
 	    case MACH_PORT_TYPE_RECEIVE:
 	    case MACH_PORT_TYPE_SEND_RECEIVE:
@@ -665,6 +669,14 @@
 		break;
 	    }
 
+	    case MACH_PORT_TYPE_LABELH: {
+	      ipc_object_t lh = entry->ie_object;
+	      entry->ie_object = IO_NULL;
+	      ipc_entry_dealloc (space, name, entry);
+	      ipc_object_release (lh);
+	      break;
+	    }
+
 	    case MACH_PORT_TYPE_SEND:
 	    case MACH_PORT_TYPE_RECEIVE:
 	    case MACH_PORT_TYPE_SEND_RECEIVE:
@@ -999,6 +1011,21 @@
 		break;
 	    }
 
+	    case MACH_PORT_RIGHT_LABELH: {
+	      ipc_object_t lh = entry->ie_object;
+	      if ((bits & MACH_PORT_TYPE_LABELH) == 0)
+		goto invalid_right;
+	      if (delta == 0)
+		goto success;
+	      else if (delta != -1)
+		goto invalid_value;
+	      entry->ie_object = IO_NULL;
+	      ipc_entry_dealloc (space, name, entry);
+	      ipc_object_release (lh);
+	      is_write_unlock (space);
+	      break;
+	    }
+
 	    case MACH_PORT_RIGHT_RECEIVE: {
 		ipc_port_t port;
 		ipc_port_t dnrequest = IP_NULL;

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/ipc/mach_port.c#3 (text+ko) ====

@@ -81,6 +81,7 @@
 #include <ipc/ipc_pset.h>
 #include <ipc/ipc_right.h>
 #include <ipc/ipc_kmsg.h>
+#include <ipc/ipc_labelh.h>
 #include <kern/misc_protos.h>
 
 /*
@@ -1753,7 +1754,7 @@
 	return kr;
 }
 
-/* Don't pass something other than a port, it doesn't check the type yet. */
+/* also works on label handles */
 
 kern_return_t
 mach_get_port_label (ipc_space_t space, mach_port_name_t name, vm_offset_t outlabel)
@@ -1771,6 +1772,9 @@
 	if (kr != KERN_SUCCESS)
 		return kr;
 
+	switch (io_otype (entry->ie_object))
+	  {
+	  case IOT_PORT:{
 	ipc_port_t port = (ipc_port_t) entry->ie_object;
 
 	ip_lock (port);
@@ -1778,7 +1782,22 @@
 	mac_externalize_port_label (&port->ip_label, "sebsd", outlabel, 512, 0);
 
 	ip_unlock (port);
-	return kr;
+	  }
+	return 0;
+
+	  case IOT_LABELH:
+	    {
+	      ipc_labelh_t lh = (ipc_labelh_t) entry->ie_object;
+	      io_lock (&lh->lh_object);
+	      is_write_unlock (space);
+	      mac_externalize_port_label (&lh->lh_label, "sebsd", outlabel, 512, 0);
+	      io_unlock (&lh->lh_object);
+	    }
+	    return 0;
+	  }
+
+	is_write_unlock (space);
+	return KERN_INVALID_ARGUMENT;
 }
 
 kern_return_t
@@ -1803,6 +1822,11 @@
 	if (kr != KERN_SUCCESS)
 		return kr;
 
+	if (IOT_PORT != io_otype(entry->ie_object)) {
+	  is_write_unlock (space);
+	  return KERN_INVALID_RIGHT;
+	}
+
 	ipc_port_t port = (ipc_port_t) entry->ie_object;
 
 	ip_lock (port);

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/kern/task.c#3 (text+ko) ====

@@ -1824,8 +1824,9 @@
 {
   struct label  subjl;
   ipc_entry_t   entry;
-  ipc_port_t    objp;
+  ipc_object_t  objp;
   kern_return_t kr;
+  struct label  *objl;
 
   if (space == IS_NULL || space->is_task == NULL)
     return KERN_INVALID_TASK;
@@ -1848,18 +1849,71 @@
       return kr;
     }
 
-  objp = (ipc_port_t) entry->ie_object;
+  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,
+		       vm_offset_t serv, vm_offset_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;
 
-  ip_lock (objp);
-  rc = mac_check_service_access (&subjl, &objp->ip_label, serv, perm);
-  ip_unlock (objp);
+  objp = obji->ie_object;
+  subp = subi->ie_object;
   is_write_unlock (space);
 
-  mac_destroy_task_label (&subjl);
+  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/sedarwin/apsl/xnu/osfmk/mach/port.h#2 (text+ko) ====

@@ -192,7 +192,8 @@
 #define MACH_PORT_RIGHT_SEND_ONCE	((mach_port_right_t) 2)
 #define MACH_PORT_RIGHT_PORT_SET	((mach_port_right_t) 3)
 #define MACH_PORT_RIGHT_DEAD_NAME	((mach_port_right_t) 4)
-#define MACH_PORT_RIGHT_NUMBER		((mach_port_right_t) 5)
+#define MACH_PORT_RIGHT_LABELH	        ((mach_port_right_t) 5)
+#define MACH_PORT_RIGHT_NUMBER		((mach_port_right_t) 6)
 
 typedef natural_t mach_port_type_t;
 typedef mach_port_type_t *mach_port_type_array_t;
@@ -206,6 +207,7 @@
 #define MACH_PORT_TYPE_SEND_ONCE    MACH_PORT_TYPE(MACH_PORT_RIGHT_SEND_ONCE)
 #define MACH_PORT_TYPE_PORT_SET	    MACH_PORT_TYPE(MACH_PORT_RIGHT_PORT_SET)
 #define MACH_PORT_TYPE_DEAD_NAME    MACH_PORT_TYPE(MACH_PORT_RIGHT_DEAD_NAME)
+#define MACH_PORT_TYPE_LABELH       MACH_PORT_TYPE(MACH_PORT_RIGHT_LABELH)
 
 /* Convenient combinations. */
 

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/osfmk/mach/security.defs#2 (text+ko) ====

@@ -24,6 +24,8 @@
 routine mach_get_task_label(task      : task_t;
 			    out label : labelstr_t);
 
+/* also works on label handles */
+
 routine mach_get_port_label(task      : ipc_space_t;
 			    name      : mach_port_name_t;
 			    out label : labelstr_t);
@@ -45,3 +47,15 @@
 				   object  : mach_port_name_t;
 				   service : labelstr_t;
 				   perm    : labelstr_t);
+
+/* Uses ports (or label handles) for both subject and object. */
+
+routine mac_check_port_access(task    : ipc_space_t;
+			      subject : mach_port_name_t;
+			      object  : mach_port_name_t;
+			      service : labelstr_t;
+			      perm    : labelstr_t);
+
+routine mac_label_new(task     : ipc_space_t;
+		      out name : mach_port_name_t;
+		      label    : labelstr_t);



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