PERFORCE change 105783 for review

Todd Miller millert at FreeBSD.org
Thu Sep 7 13:51:46 UTC 2006


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

Change 105783 by millert at millert_g5tower on 2006/09/07 13:30:49

	Start labelling Mach threads.  When a thread is created it
	gets a reference to the label handle of the task that created
	it.  Note that one task can create threads in another task.
	
	Changes to the task label to propagate to its own threads
	that contain a reference to its label.  Changes will *not*
	be propagated to threads created in another task.  Those
	threads will retain the label of the task that created them
	(which will not change).  This is considered a feature (but
	I could be convinced otherwise).

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/osfmk/kern/task.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/osfmk/kern/thread.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/osfmk/kern/thread.h#2 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/osfmk/kern/task.c#5 (text+ko) ====

@@ -1686,29 +1686,78 @@
 void
 mac_task_update_label(
 	struct label	*pl,
-	struct task	*t)
+	struct task	*task)
 {
+	thread_t thread;
+	ipc_labelh_t oldlabel;
+
+	tasklabel_lock(task);
+	oldlabel = task->label;
 
-	tasklabel_lock(t);
-	t->label = labelh_modify(t->label);
-	mac_cred_copy_to_task(pl, &t->maclabel);
-	tasklabel_unlock(t);
-	ip_lock(t->itk_self);
-	mac_port_update_from_cred(pl, &t->itk_self->ip_label);
-	ip_unlock(t->itk_self);
+	/*
+	 * For each thread in the task, release a reference to the label
+	 * handle in the thread if it matches the parent's.
+	 * XXX - do we need to hold the task while this is going on?
+	 */
+	queue_iterate(&task->threads, thread, thread_t, task_threads) {
+		if (thread->label == oldlabel)
+			lh_release(oldlabel);
+	}
+	task->label = labelh_modify(task->label, 0);
+	mac_cred_copy_to_task(pl, &task->maclabel);
+	/*
+	 * Replace the old label in the task's threads with the new one.
+	 */
+	queue_iterate(&task->threads, thread, thread_t, task_threads) {
+		if (thread->label == oldlabel) {
+			thread->label = task->label;
+			lh_reference(task->label);
+		}
+	}
+	/* Free old label if it is no longer in use.  */
+	if (task->label != oldlabel)
+		lh_check_unlock(oldlabel);
+	tasklabel_unlock(task);
+	ip_lock(task->itk_self);
+	mac_port_update_from_cred(pl, &task->itk_self->ip_label);
+	ip_unlock(task->itk_self);
 }
 
 void
 mac_task_modify_label(
-	struct task	*pt,
+	struct task	*task,
 	void		*arg,
 	void (*f)	(struct label *l, void *arg))
 {
+	thread_t thread;
+	ipc_labelh_t oldlabel;
 
-	tasklabel_lock(pt);
-	pt->label = labelh_modify(pt->label);
-	(*f)(&pt->maclabel, arg);
-	tasklabel_unlock(pt);
+	tasklabel_lock(task);
+	oldlabel = task->label;
+
+	/*
+	 * For each thread in the task, release a reference to the label
+	 * handle in the thread if it matches the parent's.
+	 * XXX - do we need to hold the task while this is going on?
+	 */
+	queue_iterate(&task->threads, thread, thread_t, task_threads) {
+		if (thread->label == oldlabel)
+			lh_release(oldlabel);
+	}
+	task->label = labelh_modify(task->label, 0);
+	(*f)(&task->maclabel, arg);
+	/*
+	 * Replace the old label in the task's threads with the new one.
+	 */
+	queue_iterate(&task->threads, thread, thread_t, task_threads) {
+		if (thread->label == oldlabel) {
+			thread->label = task->label;
+			lh_reference(task->label);
+		}
+	}
+	/* Free old label if it is no longer in use.  */
+	if (task->label != oldlabel)
+		lh_check_unlock(oldlabel);
+	tasklabel_unlock(task);
 }
-
 #endif

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/osfmk/kern/thread.c#2 (text+ko) ====

@@ -383,6 +383,10 @@
 
 	machine_thread_destroy(thread);
 
+#ifdef MAC
+	labelh_release(task->label);
+#endif
+
 	zfree(thread_zone, thread);
 }
 
@@ -657,6 +661,11 @@
 	new_thread->pri_shift = new_thread->processor_set->pri_shift;
 	compute_priority(new_thread, FALSE);
 
+#ifdef MAC
+	labelh_reference(parent_task->label);
+	new_thread->label = parent_task->label;
+#endif
+
 	new_thread->active = TRUE;
 
 	*out_thread = new_thread;

==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/osfmk/kern/thread.h#2 (text+ko) ====

@@ -114,7 +114,9 @@
 #include <kern/timer_call.h>
 #include <kern/task.h>
 #include <kern/exception.h>
+#include <security/_label.h>
 
+#include <ipc/ipc_labelh.h>
 #include <ipc/ipc_kmsg.h>
 
 #include <machine/cpu_data.h>
@@ -347,6 +349,10 @@
 #ifdef	MACH_BSD
 		void					*uthread;
 #endif
+
+#ifdef MAC
+		ipc_labelh_t				label;
+#endif
 };
 
 #define ith_state		saved.receive.state


More information about the trustedbsd-cvs mailing list