SELinux: add boundary support and thread context assignment
The purpose of this patch is to assign per-thread security context under a constraint. It enables multi-threaded server application to kick a request handler with its fair security context, and helps some of userspace object managers to handle user's request. When we assign a per-thread security context, it must not have wider permissions than the original one. Because a multi-threaded process shares a single local memory, an arbitary per-thread security context also means another thread can easily refer violated information. The constraint on a per-thread security context requires a new domain has to be equal or weaker than its original one, when it tries to assign a per-thread security context. Bounds relationship between two types is a way to ensure a domain can never have wider permission than its bounds. We can define it in two explicit or implicit ways. The first way is using new TYPEBOUNDS statement. It enables to define a boundary of types explicitly. The other one expand the concept of existing named based hierarchy. If we defines a type with "." separated name like "httpd_t.php", toolchain implicitly set its bounds on "httpd_t". This feature requires a new policy version. The 24th version (POLICYDB_VERSION_BOUNDARY) enables to ship them into kernel space, and the following patch enables to handle it. Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
committed by
James Morris
parent
da31894ed7
commit
d9250dea3f
@@ -5226,8 +5226,12 @@ static int selinux_setprocattr(struct task_struct *p,
|
||||
|
||||
if (sid == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Only allow single threaded processes to change context */
|
||||
/*
|
||||
* SELinux allows to change context in the following case only.
|
||||
* - Single threaded processes.
|
||||
* - Multi threaded processes intend to change its context into
|
||||
* more restricted domain (defined by TYPEBOUNDS statement).
|
||||
*/
|
||||
if (atomic_read(&p->mm->mm_users) != 1) {
|
||||
struct task_struct *g, *t;
|
||||
struct mm_struct *mm = p->mm;
|
||||
@@ -5235,11 +5239,16 @@ static int selinux_setprocattr(struct task_struct *p,
|
||||
do_each_thread(g, t) {
|
||||
if (t->mm == mm && t != p) {
|
||||
read_unlock(&tasklist_lock);
|
||||
return -EPERM;
|
||||
error = security_bounded_transition(tsec->sid, sid);
|
||||
if (!error)
|
||||
goto boundary_ok;
|
||||
|
||||
return error;
|
||||
}
|
||||
} while_each_thread(g, t);
|
||||
read_unlock(&tasklist_lock);
|
||||
}
|
||||
boundary_ok:
|
||||
|
||||
/* Check permissions for the transition. */
|
||||
error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
|
||||
|
||||
Reference in New Issue
Block a user