Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Sep 2006 13:31:09 GMT
From:      Todd Miller <millert@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 105783 for review
Message-ID:  <200609071331.k87DV94f011339@repoman.freebsd.org>

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

Change 105783 by millert@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



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