aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6b5790bba8f9..89f446d86054 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5226,8 +5226,12 @@ static int selinux_setprocattr(struct task_struct *p,
5226 5226
5227 if (sid == 0) 5227 if (sid == 0)
5228 return -EINVAL; 5228 return -EINVAL;
5229 5229 /*
5230 /* Only allow single threaded processes to change context */ 5230 * SELinux allows to change context in the following case only.
5231 * - Single threaded processes.
5232 * - Multi threaded processes intend to change its context into
5233 * more restricted domain (defined by TYPEBOUNDS statement).
5234 */
5231 if (atomic_read(&p->mm->mm_users) != 1) { 5235 if (atomic_read(&p->mm->mm_users) != 1) {
5232 struct task_struct *g, *t; 5236 struct task_struct *g, *t;
5233 struct mm_struct *mm = p->mm; 5237 struct mm_struct *mm = p->mm;
@@ -5235,11 +5239,16 @@ static int selinux_setprocattr(struct task_struct *p,
5235 do_each_thread(g, t) { 5239 do_each_thread(g, t) {
5236 if (t->mm == mm && t != p) { 5240 if (t->mm == mm && t != p) {
5237 read_unlock(&tasklist_lock); 5241 read_unlock(&tasklist_lock);
5238 return -EPERM; 5242 error = security_bounded_transition(tsec->sid, sid);
5243 if (!error)
5244 goto boundary_ok;
5245
5246 return error;
5239 } 5247 }
5240 } while_each_thread(g, t); 5248 } while_each_thread(g, t);
5241 read_unlock(&tasklist_lock); 5249 read_unlock(&tasklist_lock);
5242 } 5250 }
5251boundary_ok:
5243 5252
5244 /* Check permissions for the transition. */ 5253 /* Check permissions for the transition. */
5245 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, 5254 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,