Skip to content

Commit eb1231f

Browse files
committed
selinux: clarify task subjective and objective credentials
SELinux has a function, task_sid(), which returns the task's objective credentials, but unfortunately is used in a few places where the subjective task credentials should be used. Most notably in the new security_task_getsecid_subj() LSM hook. This patch fixes this and attempts to make things more obvious by introducing a new function, task_sid_subj(), and renaming the existing task_sid() function to task_sid_obj(). This patch also adds an interesting function in task_sid_binder(). The task_sid_binder() function has a comment which hopefully describes it's reason for being, but it basically boils down to the simple fact that we can't safely access another task's subjective credentials so in the case of binder we need to stick with the objective credentials regardless. Reviewed-by: Richard Guy Briggs <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 4ebd765 commit eb1231f

File tree

1 file changed

+73
-39
lines changed

1 file changed

+73
-39
lines changed

security/selinux/hooks.c

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,23 @@ static inline u32 cred_sid(const struct cred *cred)
229229
return tsec->sid;
230230
}
231231

232+
/*
233+
* get the subjective security ID of a task
234+
*/
235+
static inline u32 task_sid_subj(const struct task_struct *task)
236+
{
237+
u32 sid;
238+
239+
rcu_read_lock();
240+
sid = cred_sid(rcu_dereference(task->cred));
241+
rcu_read_unlock();
242+
return sid;
243+
}
244+
232245
/*
233246
* get the objective security ID of a task
234247
*/
235-
static inline u32 task_sid(const struct task_struct *task)
248+
static inline u32 task_sid_obj(const struct task_struct *task)
236249
{
237250
u32 sid;
238251

@@ -242,6 +255,29 @@ static inline u32 task_sid(const struct task_struct *task)
242255
return sid;
243256
}
244257

258+
/*
259+
* get the security ID of a task for use with binder
260+
*/
261+
static inline u32 task_sid_binder(const struct task_struct *task)
262+
{
263+
/*
264+
* In many case where this function is used we should be using the
265+
* task's subjective SID, but we can't reliably access the subjective
266+
* creds of a task other than our own so we must use the objective
267+
* creds/SID, which are safe to access. The downside is that if a task
268+
* is temporarily overriding it's creds it will not be reflected here;
269+
* however, it isn't clear that binder would handle that case well
270+
* anyway.
271+
*
272+
* If this ever changes and we can safely reference the subjective
273+
* creds/SID of another task, this function will make it easier to
274+
* identify the various places where we make use of the task SIDs in
275+
* the binder code. It is also likely that we will need to adjust
276+
* the main drivers/android binder code as well.
277+
*/
278+
return task_sid_obj(task);
279+
}
280+
245281
static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
246282

247283
/*
@@ -2035,20 +2071,16 @@ static inline u32 open_file_to_av(struct file *file)
20352071

20362072
static int selinux_binder_set_context_mgr(struct task_struct *mgr)
20372073
{
2038-
u32 mysid = current_sid();
2039-
u32 mgrsid = task_sid(mgr);
2040-
20412074
return avc_has_perm(&selinux_state,
2042-
mysid, mgrsid, SECCLASS_BINDER,
2075+
current_sid(), task_sid_binder(mgr), SECCLASS_BINDER,
20432076
BINDER__SET_CONTEXT_MGR, NULL);
20442077
}
20452078

20462079
static int selinux_binder_transaction(struct task_struct *from,
20472080
struct task_struct *to)
20482081
{
20492082
u32 mysid = current_sid();
2050-
u32 fromsid = task_sid(from);
2051-
u32 tosid = task_sid(to);
2083+
u32 fromsid = task_sid_binder(from);
20522084
int rc;
20532085

20542086
if (mysid != fromsid) {
@@ -2059,27 +2091,24 @@ static int selinux_binder_transaction(struct task_struct *from,
20592091
return rc;
20602092
}
20612093

2062-
return avc_has_perm(&selinux_state,
2063-
fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
2064-
NULL);
2094+
return avc_has_perm(&selinux_state, fromsid, task_sid_binder(to),
2095+
SECCLASS_BINDER, BINDER__CALL, NULL);
20652096
}
20662097

20672098
static int selinux_binder_transfer_binder(struct task_struct *from,
20682099
struct task_struct *to)
20692100
{
2070-
u32 fromsid = task_sid(from);
2071-
u32 tosid = task_sid(to);
2072-
20732101
return avc_has_perm(&selinux_state,
2074-
fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
2102+
task_sid_binder(from), task_sid_binder(to),
2103+
SECCLASS_BINDER, BINDER__TRANSFER,
20752104
NULL);
20762105
}
20772106

20782107
static int selinux_binder_transfer_file(struct task_struct *from,
20792108
struct task_struct *to,
20802109
struct file *file)
20812110
{
2082-
u32 sid = task_sid(to);
2111+
u32 sid = task_sid_binder(to);
20832112
struct file_security_struct *fsec = selinux_file(file);
20842113
struct dentry *dentry = file->f_path.dentry;
20852114
struct inode_security_struct *isec;
@@ -2115,10 +2144,10 @@ static int selinux_binder_transfer_file(struct task_struct *from,
21152144
}
21162145

21172146
static int selinux_ptrace_access_check(struct task_struct *child,
2118-
unsigned int mode)
2147+
unsigned int mode)
21192148
{
21202149
u32 sid = current_sid();
2121-
u32 csid = task_sid(child);
2150+
u32 csid = task_sid_obj(child);
21222151

21232152
if (mode & PTRACE_MODE_READ)
21242153
return avc_has_perm(&selinux_state,
@@ -2131,15 +2160,15 @@ static int selinux_ptrace_access_check(struct task_struct *child,
21312160
static int selinux_ptrace_traceme(struct task_struct *parent)
21322161
{
21332162
return avc_has_perm(&selinux_state,
2134-
task_sid(parent), current_sid(), SECCLASS_PROCESS,
2135-
PROCESS__PTRACE, NULL);
2163+
task_sid_subj(parent), task_sid_obj(current),
2164+
SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
21362165
}
21372166

21382167
static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
21392168
kernel_cap_t *inheritable, kernel_cap_t *permitted)
21402169
{
21412170
return avc_has_perm(&selinux_state,
2142-
current_sid(), task_sid(target), SECCLASS_PROCESS,
2171+
current_sid(), task_sid_obj(target), SECCLASS_PROCESS,
21432172
PROCESS__GETCAP, NULL);
21442173
}
21452174

@@ -2264,7 +2293,7 @@ static u32 ptrace_parent_sid(void)
22642293
rcu_read_lock();
22652294
tracer = ptrace_parent(current);
22662295
if (tracer)
2267-
sid = task_sid(tracer);
2296+
sid = task_sid_obj(tracer);
22682297
rcu_read_unlock();
22692298

22702299
return sid;
@@ -3976,7 +4005,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
39764005
struct fown_struct *fown, int signum)
39774006
{
39784007
struct file *file;
3979-
u32 sid = task_sid(tsk);
4008+
u32 sid = task_sid_obj(tsk);
39804009
u32 perm;
39814010
struct file_security_struct *fsec;
39824011

@@ -4195,47 +4224,52 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
41954224
static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
41964225
{
41974226
return avc_has_perm(&selinux_state,
4198-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4227+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
41994228
PROCESS__SETPGID, NULL);
42004229
}
42014230

42024231
static int selinux_task_getpgid(struct task_struct *p)
42034232
{
42044233
return avc_has_perm(&selinux_state,
4205-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4234+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42064235
PROCESS__GETPGID, NULL);
42074236
}
42084237

42094238
static int selinux_task_getsid(struct task_struct *p)
42104239
{
42114240
return avc_has_perm(&selinux_state,
4212-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4241+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42134242
PROCESS__GETSESSION, NULL);
42144243
}
42154244

4216-
static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
4245+
static void selinux_task_getsecid_subj(struct task_struct *p, u32 *secid)
4246+
{
4247+
*secid = task_sid_subj(p);
4248+
}
4249+
4250+
static void selinux_task_getsecid_obj(struct task_struct *p, u32 *secid)
42174251
{
4218-
*secid = task_sid(p);
4252+
*secid = task_sid_obj(p);
42194253
}
42204254

42214255
static int selinux_task_setnice(struct task_struct *p, int nice)
42224256
{
42234257
return avc_has_perm(&selinux_state,
4224-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4258+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42254259
PROCESS__SETSCHED, NULL);
42264260
}
42274261

42284262
static int selinux_task_setioprio(struct task_struct *p, int ioprio)
42294263
{
42304264
return avc_has_perm(&selinux_state,
4231-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4265+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42324266
PROCESS__SETSCHED, NULL);
42334267
}
42344268

42354269
static int selinux_task_getioprio(struct task_struct *p)
42364270
{
42374271
return avc_has_perm(&selinux_state,
4238-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4272+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42394273
PROCESS__GETSCHED, NULL);
42404274
}
42414275

@@ -4266,7 +4300,7 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
42664300
upon context transitions. See selinux_bprm_committing_creds. */
42674301
if (old_rlim->rlim_max != new_rlim->rlim_max)
42684302
return avc_has_perm(&selinux_state,
4269-
current_sid(), task_sid(p),
4303+
current_sid(), task_sid_obj(p),
42704304
SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
42714305

42724306
return 0;
@@ -4275,21 +4309,21 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
42754309
static int selinux_task_setscheduler(struct task_struct *p)
42764310
{
42774311
return avc_has_perm(&selinux_state,
4278-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4312+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42794313
PROCESS__SETSCHED, NULL);
42804314
}
42814315

42824316
static int selinux_task_getscheduler(struct task_struct *p)
42834317
{
42844318
return avc_has_perm(&selinux_state,
4285-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4319+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42864320
PROCESS__GETSCHED, NULL);
42874321
}
42884322

42894323
static int selinux_task_movememory(struct task_struct *p)
42904324
{
42914325
return avc_has_perm(&selinux_state,
4292-
current_sid(), task_sid(p), SECCLASS_PROCESS,
4326+
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
42934327
PROCESS__SETSCHED, NULL);
42944328
}
42954329

@@ -4308,14 +4342,14 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
43084342
else
43094343
secid = cred_sid(cred);
43104344
return avc_has_perm(&selinux_state,
4311-
secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
4345+
secid, task_sid_obj(p), SECCLASS_PROCESS, perm, NULL);
43124346
}
43134347

43144348
static void selinux_task_to_inode(struct task_struct *p,
43154349
struct inode *inode)
43164350
{
43174351
struct inode_security_struct *isec = selinux_inode(inode);
4318-
u32 sid = task_sid(p);
4352+
u32 sid = task_sid_obj(p);
43194353

43204354
spin_lock(&isec->lock);
43214355
isec->sclass = inode_mode_to_security_class(inode->i_mode);
@@ -6208,7 +6242,7 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m
62086242
struct ipc_security_struct *isec;
62096243
struct msg_security_struct *msec;
62106244
struct common_audit_data ad;
6211-
u32 sid = task_sid(target);
6245+
u32 sid = task_sid_subj(target);
62126246
int rc;
62136247

62146248
isec = selinux_ipc(msq);
@@ -7205,8 +7239,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
72057239
LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
72067240
LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
72077241
LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
7208-
LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid),
7209-
LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid),
7242+
LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid_subj),
7243+
LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid_obj),
72107244
LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
72117245
LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
72127246
LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),

0 commit comments

Comments
 (0)