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