PERFORCE change 46537 for review
Andrew Reisse
areisse at FreeBSD.org
Thu Feb 5 15:20:07 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=46537
Change 46537 by areisse at 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);
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