diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/selinux/hooks.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 21a592184633..91b06f2aa963 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -161,7 +161,7 @@ static int selinux_secmark_enabled(void) | |||
| 161 | */ | 161 | */ |
| 162 | static void cred_init_security(void) | 162 | static void cred_init_security(void) |
| 163 | { | 163 | { |
| 164 | struct cred *cred = (struct cred *) current->cred; | 164 | struct cred *cred = (struct cred *) current->real_cred; |
| 165 | struct task_security_struct *tsec; | 165 | struct task_security_struct *tsec; |
| 166 | 166 | ||
| 167 | tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); | 167 | tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); |
| @@ -184,7 +184,7 @@ static inline u32 cred_sid(const struct cred *cred) | |||
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | /* | 186 | /* |
| 187 | * get the security ID of a task | 187 | * get the objective security ID of a task |
| 188 | */ | 188 | */ |
| 189 | static inline u32 task_sid(const struct task_struct *task) | 189 | static inline u32 task_sid(const struct task_struct *task) |
| 190 | { | 190 | { |
| @@ -197,7 +197,7 @@ static inline u32 task_sid(const struct task_struct *task) | |||
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | /* | 199 | /* |
| 200 | * get the security ID of the current task | 200 | * get the subjective security ID of the current task |
| 201 | */ | 201 | */ |
| 202 | static inline u32 current_sid(void) | 202 | static inline u32 current_sid(void) |
| 203 | { | 203 | { |
| @@ -1395,6 +1395,7 @@ static int cred_has_perm(const struct cred *actor, | |||
| 1395 | * Check permission between a pair of tasks, e.g. signal checks, | 1395 | * Check permission between a pair of tasks, e.g. signal checks, |
| 1396 | * fork check, ptrace check, etc. | 1396 | * fork check, ptrace check, etc. |
| 1397 | * tsk1 is the actor and tsk2 is the target | 1397 | * tsk1 is the actor and tsk2 is the target |
| 1398 | * - this uses the default subjective creds of tsk1 | ||
| 1398 | */ | 1399 | */ |
| 1399 | static int task_has_perm(const struct task_struct *tsk1, | 1400 | static int task_has_perm(const struct task_struct *tsk1, |
| 1400 | const struct task_struct *tsk2, | 1401 | const struct task_struct *tsk2, |
| @@ -1410,6 +1411,22 @@ static int task_has_perm(const struct task_struct *tsk1, | |||
| 1410 | return avc_has_perm(sid1, sid2, SECCLASS_PROCESS, perms, NULL); | 1411 | return avc_has_perm(sid1, sid2, SECCLASS_PROCESS, perms, NULL); |
| 1411 | } | 1412 | } |
| 1412 | 1413 | ||
| 1414 | /* | ||
| 1415 | * Check permission between current and another task, e.g. signal checks, | ||
| 1416 | * fork check, ptrace check, etc. | ||
| 1417 | * current is the actor and tsk2 is the target | ||
| 1418 | * - this uses current's subjective creds | ||
| 1419 | */ | ||
| 1420 | static int current_has_perm(const struct task_struct *tsk, | ||
| 1421 | u32 perms) | ||
| 1422 | { | ||
| 1423 | u32 sid, tsid; | ||
| 1424 | |||
| 1425 | sid = current_sid(); | ||
| 1426 | tsid = task_sid(tsk); | ||
| 1427 | return avc_has_perm(sid, tsid, SECCLASS_PROCESS, perms, NULL); | ||
| 1428 | } | ||
| 1429 | |||
| 1413 | #if CAP_LAST_CAP > 63 | 1430 | #if CAP_LAST_CAP > 63 |
| 1414 | #error Fix SELinux to handle capabilities > 63. | 1431 | #error Fix SELinux to handle capabilities > 63. |
| 1415 | #endif | 1432 | #endif |
| @@ -1807,7 +1824,7 @@ static int selinux_ptrace_may_access(struct task_struct *child, | |||
| 1807 | return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); | 1824 | return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); |
| 1808 | } | 1825 | } |
| 1809 | 1826 | ||
| 1810 | return task_has_perm(current, child, PROCESS__PTRACE); | 1827 | return current_has_perm(child, PROCESS__PTRACE); |
| 1811 | } | 1828 | } |
| 1812 | 1829 | ||
| 1813 | static int selinux_ptrace_traceme(struct task_struct *parent) | 1830 | static int selinux_ptrace_traceme(struct task_struct *parent) |
| @@ -1826,7 +1843,7 @@ static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | |||
| 1826 | { | 1843 | { |
| 1827 | int error; | 1844 | int error; |
| 1828 | 1845 | ||
| 1829 | error = task_has_perm(current, target, PROCESS__GETCAP); | 1846 | error = current_has_perm(target, PROCESS__GETCAP); |
| 1830 | if (error) | 1847 | if (error) |
| 1831 | return error; | 1848 | return error; |
| 1832 | 1849 | ||
| @@ -3071,7 +3088,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
| 3071 | } else if (!vma->vm_file && | 3088 | } else if (!vma->vm_file && |
| 3072 | vma->vm_start <= vma->vm_mm->start_stack && | 3089 | vma->vm_start <= vma->vm_mm->start_stack && |
| 3073 | vma->vm_end >= vma->vm_mm->start_stack) { | 3090 | vma->vm_end >= vma->vm_mm->start_stack) { |
| 3074 | rc = task_has_perm(current, current, PROCESS__EXECSTACK); | 3091 | rc = current_has_perm(current, PROCESS__EXECSTACK); |
| 3075 | } else if (vma->vm_file && vma->anon_vma) { | 3092 | } else if (vma->vm_file && vma->anon_vma) { |
| 3076 | /* | 3093 | /* |
| 3077 | * We are making executable a file mapping that has | 3094 | * We are making executable a file mapping that has |
| @@ -3220,7 +3237,7 @@ static int selinux_task_create(unsigned long clone_flags) | |||
| 3220 | if (rc) | 3237 | if (rc) |
| 3221 | return rc; | 3238 | return rc; |
| 3222 | 3239 | ||
| 3223 | return task_has_perm(current, current, PROCESS__FORK); | 3240 | return current_has_perm(current, PROCESS__FORK); |
| 3224 | } | 3241 | } |
| 3225 | 3242 | ||
| 3226 | /* | 3243 | /* |
| @@ -3285,17 +3302,17 @@ static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags) | |||
| 3285 | 3302 | ||
| 3286 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) | 3303 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) |
| 3287 | { | 3304 | { |
| 3288 | return task_has_perm(current, p, PROCESS__SETPGID); | 3305 | return current_has_perm(p, PROCESS__SETPGID); |
| 3289 | } | 3306 | } |
| 3290 | 3307 | ||
| 3291 | static int selinux_task_getpgid(struct task_struct *p) | 3308 | static int selinux_task_getpgid(struct task_struct *p) |
| 3292 | { | 3309 | { |
| 3293 | return task_has_perm(current, p, PROCESS__GETPGID); | 3310 | return current_has_perm(p, PROCESS__GETPGID); |
| 3294 | } | 3311 | } |
| 3295 | 3312 | ||
| 3296 | static int selinux_task_getsid(struct task_struct *p) | 3313 | static int selinux_task_getsid(struct task_struct *p) |
| 3297 | { | 3314 | { |
| 3298 | return task_has_perm(current, p, PROCESS__GETSESSION); | 3315 | return current_has_perm(p, PROCESS__GETSESSION); |
| 3299 | } | 3316 | } |
| 3300 | 3317 | ||
| 3301 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | 3318 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) |
| @@ -3317,7 +3334,7 @@ static int selinux_task_setnice(struct task_struct *p, int nice) | |||
| 3317 | if (rc) | 3334 | if (rc) |
| 3318 | return rc; | 3335 | return rc; |
| 3319 | 3336 | ||
| 3320 | return task_has_perm(current, p, PROCESS__SETSCHED); | 3337 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3321 | } | 3338 | } |
| 3322 | 3339 | ||
| 3323 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | 3340 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) |
| @@ -3328,12 +3345,12 @@ static int selinux_task_setioprio(struct task_struct *p, int ioprio) | |||
| 3328 | if (rc) | 3345 | if (rc) |
| 3329 | return rc; | 3346 | return rc; |
| 3330 | 3347 | ||
| 3331 | return task_has_perm(current, p, PROCESS__SETSCHED); | 3348 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3332 | } | 3349 | } |
| 3333 | 3350 | ||
| 3334 | static int selinux_task_getioprio(struct task_struct *p) | 3351 | static int selinux_task_getioprio(struct task_struct *p) |
| 3335 | { | 3352 | { |
| 3336 | return task_has_perm(current, p, PROCESS__GETSCHED); | 3353 | return current_has_perm(p, PROCESS__GETSCHED); |
| 3337 | } | 3354 | } |
| 3338 | 3355 | ||
| 3339 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) | 3356 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) |
| @@ -3350,7 +3367,7 @@ static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim | |||
| 3350 | later be used as a safe reset point for the soft limit | 3367 | later be used as a safe reset point for the soft limit |
| 3351 | upon context transitions. See selinux_bprm_committing_creds. */ | 3368 | upon context transitions. See selinux_bprm_committing_creds. */ |
| 3352 | if (old_rlim->rlim_max != new_rlim->rlim_max) | 3369 | if (old_rlim->rlim_max != new_rlim->rlim_max) |
| 3353 | return task_has_perm(current, current, PROCESS__SETRLIMIT); | 3370 | return current_has_perm(current, PROCESS__SETRLIMIT); |
| 3354 | 3371 | ||
| 3355 | return 0; | 3372 | return 0; |
| 3356 | } | 3373 | } |
| @@ -3363,17 +3380,17 @@ static int selinux_task_setscheduler(struct task_struct *p, int policy, struct s | |||
| 3363 | if (rc) | 3380 | if (rc) |
| 3364 | return rc; | 3381 | return rc; |
| 3365 | 3382 | ||
| 3366 | return task_has_perm(current, p, PROCESS__SETSCHED); | 3383 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3367 | } | 3384 | } |
| 3368 | 3385 | ||
| 3369 | static int selinux_task_getscheduler(struct task_struct *p) | 3386 | static int selinux_task_getscheduler(struct task_struct *p) |
| 3370 | { | 3387 | { |
| 3371 | return task_has_perm(current, p, PROCESS__GETSCHED); | 3388 | return current_has_perm(p, PROCESS__GETSCHED); |
| 3372 | } | 3389 | } |
| 3373 | 3390 | ||
| 3374 | static int selinux_task_movememory(struct task_struct *p) | 3391 | static int selinux_task_movememory(struct task_struct *p) |
| 3375 | { | 3392 | { |
| 3376 | return task_has_perm(current, p, PROCESS__SETSCHED); | 3393 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3377 | } | 3394 | } |
| 3378 | 3395 | ||
| 3379 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, | 3396 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, |
| @@ -3394,7 +3411,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, | |||
| 3394 | rc = avc_has_perm(secid, task_sid(p), | 3411 | rc = avc_has_perm(secid, task_sid(p), |
| 3395 | SECCLASS_PROCESS, perm, NULL); | 3412 | SECCLASS_PROCESS, perm, NULL); |
| 3396 | else | 3413 | else |
| 3397 | rc = task_has_perm(current, p, perm); | 3414 | rc = current_has_perm(p, perm); |
| 3398 | return rc; | 3415 | return rc; |
| 3399 | } | 3416 | } |
| 3400 | 3417 | ||
| @@ -5250,7 +5267,7 @@ static int selinux_getprocattr(struct task_struct *p, | |||
| 5250 | unsigned len; | 5267 | unsigned len; |
| 5251 | 5268 | ||
| 5252 | if (current != p) { | 5269 | if (current != p) { |
| 5253 | error = task_has_perm(current, p, PROCESS__GETATTR); | 5270 | error = current_has_perm(p, PROCESS__GETATTR); |
| 5254 | if (error) | 5271 | if (error) |
| 5255 | return error; | 5272 | return error; |
| 5256 | } | 5273 | } |
| @@ -5309,15 +5326,15 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 5309 | * above restriction is ever removed. | 5326 | * above restriction is ever removed. |
| 5310 | */ | 5327 | */ |
| 5311 | if (!strcmp(name, "exec")) | 5328 | if (!strcmp(name, "exec")) |
| 5312 | error = task_has_perm(current, p, PROCESS__SETEXEC); | 5329 | error = current_has_perm(p, PROCESS__SETEXEC); |
| 5313 | else if (!strcmp(name, "fscreate")) | 5330 | else if (!strcmp(name, "fscreate")) |
| 5314 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); | 5331 | error = current_has_perm(p, PROCESS__SETFSCREATE); |
| 5315 | else if (!strcmp(name, "keycreate")) | 5332 | else if (!strcmp(name, "keycreate")) |
| 5316 | error = task_has_perm(current, p, PROCESS__SETKEYCREATE); | 5333 | error = current_has_perm(p, PROCESS__SETKEYCREATE); |
| 5317 | else if (!strcmp(name, "sockcreate")) | 5334 | else if (!strcmp(name, "sockcreate")) |
| 5318 | error = task_has_perm(current, p, PROCESS__SETSOCKCREATE); | 5335 | error = current_has_perm(p, PROCESS__SETSOCKCREATE); |
| 5319 | else if (!strcmp(name, "current")) | 5336 | else if (!strcmp(name, "current")) |
| 5320 | error = task_has_perm(current, p, PROCESS__SETCURRENT); | 5337 | error = current_has_perm(p, PROCESS__SETCURRENT); |
| 5321 | else | 5338 | else |
| 5322 | error = -EINVAL; | 5339 | error = -EINVAL; |
| 5323 | if (error) | 5340 | if (error) |
