diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 82 |
1 files changed, 79 insertions, 3 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 54adc9d31e92..79c16e31c884 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1903,13 +1903,13 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data) | |||
1903 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); | 1903 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); |
1904 | } | 1904 | } |
1905 | 1905 | ||
1906 | static int selinux_sb_statfs(struct super_block *sb) | 1906 | static int selinux_sb_statfs(struct dentry *dentry) |
1907 | { | 1907 | { |
1908 | struct avc_audit_data ad; | 1908 | struct avc_audit_data ad; |
1909 | 1909 | ||
1910 | AVC_AUDIT_DATA_INIT(&ad,FS); | 1910 | AVC_AUDIT_DATA_INIT(&ad,FS); |
1911 | ad.u.fs.dentry = sb->s_root; | 1911 | ad.u.fs.dentry = dentry->d_sb->s_root; |
1912 | return superblock_has_perm(current, sb, FILESYSTEM__GETATTR, &ad); | 1912 | return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
1913 | } | 1913 | } |
1914 | 1914 | ||
1915 | static int selinux_mount(char * dev_name, | 1915 | static int selinux_mount(char * dev_name, |
@@ -2645,6 +2645,11 @@ static int selinux_task_setnice(struct task_struct *p, int nice) | |||
2645 | return task_has_perm(current,p, PROCESS__SETSCHED); | 2645 | return task_has_perm(current,p, PROCESS__SETSCHED); |
2646 | } | 2646 | } |
2647 | 2647 | ||
2648 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | ||
2649 | { | ||
2650 | return task_has_perm(current, p, PROCESS__SETSCHED); | ||
2651 | } | ||
2652 | |||
2648 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) | 2653 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) |
2649 | { | 2654 | { |
2650 | struct rlimit *old_rlim = current->signal->rlim + resource; | 2655 | struct rlimit *old_rlim = current->signal->rlim + resource; |
@@ -2674,6 +2679,11 @@ static int selinux_task_getscheduler(struct task_struct *p) | |||
2674 | return task_has_perm(current, p, PROCESS__GETSCHED); | 2679 | return task_has_perm(current, p, PROCESS__GETSCHED); |
2675 | } | 2680 | } |
2676 | 2681 | ||
2682 | static int selinux_task_movememory(struct task_struct *p) | ||
2683 | { | ||
2684 | return task_has_perm(current, p, PROCESS__SETSCHED); | ||
2685 | } | ||
2686 | |||
2677 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) | 2687 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) |
2678 | { | 2688 | { |
2679 | u32 perm; | 2689 | u32 perm; |
@@ -4252,6 +4262,57 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4252 | return size; | 4262 | return size; |
4253 | } | 4263 | } |
4254 | 4264 | ||
4265 | #ifdef CONFIG_KEYS | ||
4266 | |||
4267 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk) | ||
4268 | { | ||
4269 | struct task_security_struct *tsec = tsk->security; | ||
4270 | struct key_security_struct *ksec; | ||
4271 | |||
4272 | ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); | ||
4273 | if (!ksec) | ||
4274 | return -ENOMEM; | ||
4275 | |||
4276 | ksec->obj = k; | ||
4277 | ksec->sid = tsec->sid; | ||
4278 | k->security = ksec; | ||
4279 | |||
4280 | return 0; | ||
4281 | } | ||
4282 | |||
4283 | static void selinux_key_free(struct key *k) | ||
4284 | { | ||
4285 | struct key_security_struct *ksec = k->security; | ||
4286 | |||
4287 | k->security = NULL; | ||
4288 | kfree(ksec); | ||
4289 | } | ||
4290 | |||
4291 | static int selinux_key_permission(key_ref_t key_ref, | ||
4292 | struct task_struct *ctx, | ||
4293 | key_perm_t perm) | ||
4294 | { | ||
4295 | struct key *key; | ||
4296 | struct task_security_struct *tsec; | ||
4297 | struct key_security_struct *ksec; | ||
4298 | |||
4299 | key = key_ref_to_ptr(key_ref); | ||
4300 | |||
4301 | tsec = ctx->security; | ||
4302 | ksec = key->security; | ||
4303 | |||
4304 | /* if no specific permissions are requested, we skip the | ||
4305 | permission check. No serious, additional covert channels | ||
4306 | appear to be created. */ | ||
4307 | if (perm == 0) | ||
4308 | return 0; | ||
4309 | |||
4310 | return avc_has_perm(tsec->sid, ksec->sid, | ||
4311 | SECCLASS_KEY, perm, NULL); | ||
4312 | } | ||
4313 | |||
4314 | #endif | ||
4315 | |||
4255 | static struct security_operations selinux_ops = { | 4316 | static struct security_operations selinux_ops = { |
4256 | .ptrace = selinux_ptrace, | 4317 | .ptrace = selinux_ptrace, |
4257 | .capget = selinux_capget, | 4318 | .capget = selinux_capget, |
@@ -4332,9 +4393,11 @@ static struct security_operations selinux_ops = { | |||
4332 | .task_getsid = selinux_task_getsid, | 4393 | .task_getsid = selinux_task_getsid, |
4333 | .task_setgroups = selinux_task_setgroups, | 4394 | .task_setgroups = selinux_task_setgroups, |
4334 | .task_setnice = selinux_task_setnice, | 4395 | .task_setnice = selinux_task_setnice, |
4396 | .task_setioprio = selinux_task_setioprio, | ||
4335 | .task_setrlimit = selinux_task_setrlimit, | 4397 | .task_setrlimit = selinux_task_setrlimit, |
4336 | .task_setscheduler = selinux_task_setscheduler, | 4398 | .task_setscheduler = selinux_task_setscheduler, |
4337 | .task_getscheduler = selinux_task_getscheduler, | 4399 | .task_getscheduler = selinux_task_getscheduler, |
4400 | .task_movememory = selinux_task_movememory, | ||
4338 | .task_kill = selinux_task_kill, | 4401 | .task_kill = selinux_task_kill, |
4339 | .task_wait = selinux_task_wait, | 4402 | .task_wait = selinux_task_wait, |
4340 | .task_prctl = selinux_task_prctl, | 4403 | .task_prctl = selinux_task_prctl, |
@@ -4406,6 +4469,12 @@ static struct security_operations selinux_ops = { | |||
4406 | .xfrm_state_delete_security = selinux_xfrm_state_delete, | 4469 | .xfrm_state_delete_security = selinux_xfrm_state_delete, |
4407 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | 4470 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, |
4408 | #endif | 4471 | #endif |
4472 | |||
4473 | #ifdef CONFIG_KEYS | ||
4474 | .key_alloc = selinux_key_alloc, | ||
4475 | .key_free = selinux_key_free, | ||
4476 | .key_permission = selinux_key_permission, | ||
4477 | #endif | ||
4409 | }; | 4478 | }; |
4410 | 4479 | ||
4411 | static __init int selinux_init(void) | 4480 | static __init int selinux_init(void) |
@@ -4441,6 +4510,13 @@ static __init int selinux_init(void) | |||
4441 | } else { | 4510 | } else { |
4442 | printk(KERN_INFO "SELinux: Starting in permissive mode\n"); | 4511 | printk(KERN_INFO "SELinux: Starting in permissive mode\n"); |
4443 | } | 4512 | } |
4513 | |||
4514 | #ifdef CONFIG_KEYS | ||
4515 | /* Add security information to initial keyrings */ | ||
4516 | security_key_alloc(&root_user_keyring, current); | ||
4517 | security_key_alloc(&root_session_keyring, current); | ||
4518 | #endif | ||
4519 | |||
4444 | return 0; | 4520 | return 0; |
4445 | } | 4521 | } |
4446 | 4522 | ||