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>