PERFORCE change 78531 for review
Andrew Reisse
areisse at FreeBSD.org
Tue Jun 14 15:30:21 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=78531
Change 78531 by areisse at areisse_ibook on 2005/06/14 15:29:49
Convert mach label handles to be real kernel ports, instead of just
sharing the namespace. This will allow the interface to some of the
security related calls to be simplified in the future, as well as
removing the uglyness of IOT_LABELH from the system. Label handles
should also be able to be passed among processes if desired.
This submit doesn't change the policy-kernel interface, or the
kernel-user interface.
Some locking and memory issues remain (mostly because there were
locking problems with label handles before).
Affected files ...
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_init.c#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_kmsg.c#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_kmsg.h#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.c#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.h#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.c#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.h#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_right.c#3 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/mach_msg.c#4 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/mach_port.c#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/ipc_kobject.h#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.c#2 edit
.. //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.h#2 edit
Differences ...
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_init.c#2 (text+ko) ====
@@ -165,12 +165,6 @@
/* 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/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_kmsg.c#2 (text+ko) ====
@@ -239,15 +239,10 @@
mach_msg_size_t size = kmsg->ikm_size;
ipc_port_t port;
- if (kmsg->ikm_sender != IO_NULL && io_otype (&kmsg->ikm_sender->lh_object) ==
- IOT_LABELH) {
- ipc_object_release (&kmsg->ikm_sender->lh_object);
- kmsg->ikm_sender = IO_NULL;
+ if (kmsg->ikm_sender != NULL) {
+ labelh_release (kmsg->ikm_sender);
+ kmsg->ikm_sender = NULL;
}
- else if (kmsg->ikm_sender != IO_NULL && io_otype (&kmsg->ikm_sender->lh_object)
- != IOT_LABELH)
- printf ("strange otype in message label: %d\n", io_otype (&kmsg->ikm_sender->lh_object));
-
/*
* Check to see if the message is bound to the port. If so,
@@ -614,15 +609,10 @@
ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count);
}
- if (kmsg->ikm_sender != IO_NULL && io_otype (&kmsg->ikm_sender->lh_object) ==
- IOT_LABELH) {
- ipc_object_release (&kmsg->ikm_sender->lh_object);
- kmsg->ikm_sender = IO_NULL;
+ if (kmsg->ikm_sender != NULL) {
+ labelh_release (kmsg->ikm_sender);
+ kmsg->ikm_sender = NULL;
}
- else if (kmsg->ikm_sender != IO_NULL && io_otype (&kmsg->ikm_sender->lh_object)
- != IOT_LABELH)
- printf ("strange otype in message label: %d\n", io_otype (&kmsg->ikm_sender->lh_object));
-
}
/*
@@ -729,9 +719,7 @@
task_t cur = current_thread()->top_act->task;
if (cur)
{
- ipc_object_reference (&cur->label->lh_object);
- /*trailer->msgh_labels.sender = (mach_port_name_t)cur->label;*/
-
+ labelh_reference (cur->label);
kmsg->ikm_sender = cur->label;
}
else
@@ -823,7 +811,7 @@
trailer->msgh_labels.sender = 0;
- kmsg->ikm_sender = (ipc_labelh_t)IO_NULL;
+ kmsg->ikm_sender = (ipc_labelh_t)NULL;
*kmsgp = kmsg;
return MACH_MSG_SUCCESS;
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_kmsg.h#2 (text+ko) ====
@@ -78,7 +78,6 @@
#include <kern/macro_help.h>
#include <kern/kalloc.h>
#include <ipc/ipc_object.h>
-#include <ipc/ipc_labelh.h>
/*
* This structure is only the header for a kmsg buffer;
@@ -92,13 +91,14 @@
* of the message.
*/
+struct ipc_labelh;
typedef struct ipc_kmsg {
struct ipc_kmsg *ikm_next;
struct ipc_kmsg *ikm_prev;
ipc_port_t ikm_prealloc; /* port we were preallocated from */
mach_msg_size_t ikm_size;
- ipc_labelh_t ikm_sender;
+ struct ipc_labelh *ikm_sender;
mach_msg_header_t ikm_header;
} *ipc_kmsg_t;
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.c#2 (text+ko) ====
@@ -1,13 +1,16 @@
#include <ipc/ipc_space.h>
-#include <ipc/ipc_object.h>
+#include <ipc/ipc_port.h>
#include <ipc/ipc_labelh.h>
+#include <kern/ipc_kobject.h>
kern_return_t mac_label_new (ipc_space_t task, mach_port_name_t *name,
vm_offset_t labelstr)
{
ipc_labelh_t lh;
struct label inl;
+ ipc_port_t port, sport;
+ kern_return_t kr;
if (task == IS_NULL)
return (KERN_INVALID_TASK);
@@ -16,35 +19,54 @@
if (mac_internalize_port_label (&inl, labelstr))
return KERN_INVALID_ARGUMENT;
- int kr = ipc_object_alloc (task, IOT_LABELH, MACH_PORT_TYPE_LABELH, 1, name, &lh);
- if (kr)
- return kr;
+ port = ipc_port_alloc_kernel();
+ lh = kalloc(sizeof(struct ipc_labelh));
+ io_lock_init(lh);
+ lh->lh_port = port;
+ lh->lh_type = 0;
+ lh->lh_references = 1;
lh->lh_label = inl;
- io_unlock (&lh->lh_object);
+ ipc_kobject_set(port, (ipc_kobject_t)lh, IKOT_LABELH);
+
+ sport = ipc_port_make_send_locked(port);
+ ip_release(port);
+ ip_unlock(port);
+ *name = ipc_port_copyout_send (port,task);
return 0;
}
+/* This function should be used to allocate label handles
+ that are stored in other kernel objects, such as tasks.
+ They must be released along with that object.
+ The caller gets one reference, which can be applied to either the
+ port or the ipc_label_t structure itself.
+*/
ipc_labelh_t labelh_new ()
{
- ipc_labelh_t lh = (ipc_labelh_t) io_alloc (IOT_LABELH);
- io_lock_init (&(lh->lh_object));
- lh->lh_object.io_references = 1;
- lh->lh_object.io_bits = io_makebits (TRUE, IOT_LABELH, 0);
+ ipc_labelh_t lh = (ipc_labelh_t) kalloc(sizeof(struct ipc_labelh));
+ io_lock_init(lh);
+ lh->lh_port = ipc_port_alloc_kernel();
+ lh->lh_type = 0;
+ lh->lh_references = 1;
+ ipc_kobject_set(lh->lh_port, (ipc_kobject_t)lh, IKOT_LABELH);
+ ip_unlock(lh->lh_port);
return lh;
}
-/* call with old locked */
+/* call with old locked; returned object is unlocked */
ipc_labelh_t labelh_duplicate (ipc_labelh_t old)
{
- ipc_labelh_t lh = (ipc_labelh_t) io_alloc (IOT_LABELH);
- io_lock_init (&(lh->lh_object));
- lh->lh_object.io_references = 1;
- lh->lh_object.io_bits = io_makebits (TRUE, IOT_LABELH, 0);
-
+ ipc_labelh_t lh = (ipc_labelh_t) kalloc(sizeof(struct ipc_labelh));
+ io_lock_init(lh);
+ lh->lh_port = ipc_port_alloc_kernel();
+ lh->lh_type = 0;
+ lh->lh_references = 1;
+ ipc_kobject_set(lh->lh_port, (ipc_kobject_t)lh, IKOT_LABELH);
mac_init_port_label (&lh->lh_label);
mac_copy_port_label (&old->lh_label, &lh->lh_label);
+ ip_unlock(lh->lh_port);
return lh;
}
@@ -52,11 +74,34 @@
ipc_labelh_t labelh_modify (ipc_labelh_t old)
{
- if (old->lh_object.io_references == 1)
+ if (old->lh_references == 1)
return old;
ipc_labelh_t lh = labelh_duplicate (old);
- io_release (&old->lh_object);
- io_unlock (&old->lh_object);
- io_lock (&lh->lh_object);
+ lh_release(old);
+ lh_check_unlock (old);
+ lh_lock (lh);
+ return lh;
+}
+
+/* add or drop a reference on a label handle; not locked */
+
+ipc_labelh_t labelh_reference (ipc_labelh_t lh)
+{
+ lh_lock(lh);
+ lh_reference(lh);
+ lh_unlock(lh);
return lh;
}
+
+void labelh_release (ipc_labelh_t lh)
+{
+ lh_lock(lh);
+ lh_release(lh);
+ lh_check_unlock(lh);
+}
+
+void lh_free (ipc_labelh_t lh)
+{
+ ipc_object_release(lh->lh_port);
+ mac_destroy_port_label (&lh->lh_label);
+}
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_labelh.h#2 (text+ko) ====
@@ -3,17 +3,45 @@
#define _IPC_LABELH_H_
#include <kern/lock.h>
-#include <ipc/ipc_object.h>
+#include <ipc/ipc_port.h>
#include <mach/_label.h>
typedef struct ipc_labelh
{
- struct ipc_object lh_object;
- struct label lh_label;
+ int lh_references;
+ int lh_type;
+ struct label lh_label;
+ ipc_port_t lh_port;
+#if NCPUS == 1
+ usimple_lock_data_t io_lock_data;
+#else
+ decl_mutex_data(, io_lock_data)
+#endif
} *ipc_labelh_t;
-
ipc_labelh_t labelh_duplicate (ipc_labelh_t old);
ipc_labelh_t labelh_modify (ipc_labelh_t old);
+void labelh_release (ipc_labelh_t lh);
+ipc_labelh_t labelh_reference (ipc_labelh_t lh);
+void lh_free (ipc_labelh_t lh);
+
+#define lh_reference(lh) ((lh)->lh_references++)
+#define lh_release(lh) \
+MACRO_BEGIN \
+ assert ((lh)->lh_references > 0); \
+ (lh)->lh_references--; \
+MACRO_END
+
+#define lh_lock io_lock
+#define lh_unlock io_unlock
+
+#define lh_check_unlock(lh) \
+MACRO_BEGIN \
+ _VOLATILE_ natural_t _refs = (lh)->lh_references; \
+ \
+ lh_unlock(lh); \
+ if (_refs == 0) \
+ lh_free(lh); \
+MACRO_END
#endif
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.c#2 (text+ko) ====
@@ -990,17 +990,23 @@
return kr;
}
+/*
+ * Get a label out of a port, to be used by a kernel call
+ * 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.
+ */
+
struct label *io_getlabel (ipc_object_t objp)
{
- switch (io_otype (objp))
- {
- case IOT_PORT:
- return &((ipc_port_t) objp)->ip_label;
+ assert(io_otype(objp) == IOT_PORT);
+
+ ipc_port_t port = (ipc_port_t) objp;
- case IOT_LABELH:
- return &((ipc_labelh_t) objp)->lh_label;
- }
- return NULL;
+ if (ip_kotype(port) == IKOT_LABELH)
+ return &((ipc_labelh_t) port->ip_kobject)->lh_label;
+ else
+ return &port->ip_label;
}
/*
@@ -1025,10 +1031,6 @@
and calling it now causes problems. */
mac_destroy_port_label (&port->ip_label);
- }
- 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);
@@ -1080,6 +1082,7 @@
"(IOKIT_CONNECT) ",
"(IOKIT_OBJECT) ", /* 30 */
"(UPL) ",
+ "(LABELH) ",
/* << new entries here */
"(UNKNOWN) " /* magic catchall */
};
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_object.h#2 (text+ko) ====
@@ -142,8 +142,7 @@
*/
#define IOT_PORT 0
#define IOT_PORT_SET 1
-#define IOT_LABELH 2 /* a label handle */
-#define IOT_NUMBER 3 /* number of types used */
+#define IOT_NUMBER 2 /* number of types used */
extern zone_t ipc_object_zones[IOT_NUMBER];
@@ -152,7 +151,6 @@
/*
* Call the routine for io_free so that checking can be performed.
- * It is also responsible for freeing labels.
*/
extern void io_free(
unsigned int otype,
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/ipc_right.c#3 (text+ko) ====
@@ -560,10 +560,6 @@
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:
@@ -678,14 +674,6 @@
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:
@@ -1020,21 +1008,6 @@
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/sedarwin7/src/darwin/xnu/osfmk/ipc/mach_msg.c#4 (text+ko) ====
@@ -276,7 +276,7 @@
#if 1
if (option & MACH_RCV_TRAILER_ELEMENTS (MACH_RCV_TRAILER_AV)) {
- if (kmsg->ikm_sender != IO_NULL &&
+ if (kmsg->ikm_sender != NULL &&
IP_VALID(kmsg->ikm_header.msgh_remote_port)) {
mac_check_ipc_methods
(&kmsg->ikm_sender->lh_label,
@@ -288,24 +288,32 @@
memset(trailer->msgh_av.av, 0, sizeof(msg_access_vector_t));
}
+ /*
+ * The ipc_kmsg_t holds a reference to the label of a label
+ * handle, not the port. We must get a reference to the port
+ * and a send right to copyout to the receiver.
+ */
if (option & MACH_RCV_TRAILER_ELEMENTS (MACH_RCV_TRAILER_LABELS)) {
- if (kmsg->ikm_sender != IO_NULL) {
- ipc_object_t lh = &kmsg->ikm_sender->lh_object;
+
+ if (kmsg->ikm_sender != NULL) {
+ ipc_labelh_t lh = kmsg->ikm_sender;
ipc_entry_t entry;
kern_return_t kr;
- io_lock (lh);
- kr = ipc_entry_alloc (space, &trailer->msgh_labels.sender, &entry);
+ ip_lock (lh->lh_port);
+ lh->lh_port->ip_mscount++;
+ lh->lh_port->ip_srights++;
+ ip_reference (lh->lh_port);
+ ip_unlock (lh->lh_port);
+
+ kr = ipc_object_copyout (space, lh->lh_port, MACH_MSG_TYPE_PORT_SEND, 0,
+ &trailer->msgh_labels.sender);
if (kr != KERN_SUCCESS) {
+ ip_lock (lh->lh_port);
+ ip_release (lh->lh_port);
+ ip_check_unlock (lh->lh_port);
+
trailer->msgh_labels.sender = 0;
- /*ipc_object_release (lh);*/
- }
- else {
- entry->ie_bits |= (1 | MACH_PORT_TYPE_LABELH);
- entry->ie_object = lh;
- io_reference (lh);
- io_unlock (lh);
- is_write_unlock (space);
}
}
else {
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/ipc/mach_port.c#2 (text+ko) ====
@@ -1774,6 +1774,7 @@
{
ipc_entry_t entry;
kern_return_t kr;
+ struct label *l;
if (space == IS_NULL || space->is_task == NULL)
return KERN_INVALID_TASK;
@@ -1785,32 +1786,14 @@
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;
+ io_lock(entry->ie_object);
+ is_write_unlock (space);
+ l = io_getlabel(entry->ie_object);
- ip_lock (port);
- is_write_unlock (space);
- mac_externalize_port_label (&port->ip_label, policies, outlabel, 512, 0);
+ mac_externalize_port_label (l, policies, outlabel, 512, 0);
- ip_unlock (port);
- }
+ io_unlock (entry->ie_object);
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, policies, outlabel, 512, 0);
- io_unlock (&lh->lh_object);
- }
- return 0;
- }
-
- is_write_unlock (space);
- return KERN_INVALID_ARGUMENT;
}
kern_return_t
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/ipc_kobject.h#2 (text+ko) ====
@@ -110,9 +110,10 @@
#define IKOT_IOKIT_CONNECT 29
#define IKOT_IOKIT_OBJECT 30
#define IKOT_UPL 31
+#define IKOT_LABELH 32
/* << new entries here */
-#define IKOT_UNKNOWN 32 /* magic catchall */
-#define IKOT_MAX_TYPE 33 /* # of IKOT_ types */
+#define IKOT_UNKNOWN 33 /* magic catchall */
+#define IKOT_MAX_TYPE 34 /* # of IKOT_ types */
/* Please keep ipc/ipc_object.c:ikot_print_array up to date */
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.c#2 (text+ko) ====
@@ -518,7 +518,7 @@
task_prof_deallocate(task);
#ifdef MAC
- ipc_object_release (&task->label->lh_object);
+ labelh_release(task->label);
#endif
zfree(task_zone, (vm_offset_t) task);
==== //depot/projects/trustedbsd/sedarwin7/src/darwin/xnu/osfmk/kern/task.h#2 (text+ko) ====
@@ -242,11 +242,11 @@
#define maclabel label->lh_label
-#define tasklabel_lock(task) io_lock(&(task)->label->lh_object)
-#define tasklabel_unlock(task) io_unlock(&(task)->label->lh_object)
+#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->lh_object, &(b)->label->lh_object)
-#define tasklabel_unlock2(a,b) io_unlock2 (&(a)->label->lh_object, &(b)->label->lh_object)
+#define tasklabel_lock2(a,b) /*io_lock2 ((a)->label, (b)->label)*/
+#define tasklabel_unlock2(a,b) /*io_unlock2 ((a)->label, (b)->label)*/
#endif
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