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.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 79c16e31c884..28832e689800 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1099,6 +1099,17 @@ static int may_create(struct inode *dir,
1099 FILESYSTEM__ASSOCIATE, &ad); 1099 FILESYSTEM__ASSOCIATE, &ad);
1100} 1100}
1101 1101
1102/* Check whether a task can create a key. */
1103static int may_create_key(u32 ksid,
1104 struct task_struct *ctx)
1105{
1106 struct task_security_struct *tsec;
1107
1108 tsec = ctx->security;
1109
1110 return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL);
1111}
1112
1102#define MAY_LINK 0 1113#define MAY_LINK 0
1103#define MAY_UNLINK 1 1114#define MAY_UNLINK 1
1104#define MAY_RMDIR 2 1115#define MAY_RMDIR 2
@@ -1521,8 +1532,10 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm)
1521 /* Default to the current task SID. */ 1532 /* Default to the current task SID. */
1522 bsec->sid = tsec->sid; 1533 bsec->sid = tsec->sid;
1523 1534
1524 /* Reset create SID on execve. */ 1535 /* Reset fs, key, and sock SIDs on execve. */
1525 tsec->create_sid = 0; 1536 tsec->create_sid = 0;
1537 tsec->keycreate_sid = 0;
1538 tsec->sockcreate_sid = 0;
1526 1539
1527 if (tsec->exec_sid) { 1540 if (tsec->exec_sid) {
1528 newsid = tsec->exec_sid; 1541 newsid = tsec->exec_sid;
@@ -2574,9 +2587,11 @@ static int selinux_task_alloc_security(struct task_struct *tsk)
2574 tsec2->osid = tsec1->osid; 2587 tsec2->osid = tsec1->osid;
2575 tsec2->sid = tsec1->sid; 2588 tsec2->sid = tsec1->sid;
2576 2589
2577 /* Retain the exec and create SIDs across fork */ 2590 /* Retain the exec, fs, key, and sock SIDs across fork */
2578 tsec2->exec_sid = tsec1->exec_sid; 2591 tsec2->exec_sid = tsec1->exec_sid;
2579 tsec2->create_sid = tsec1->create_sid; 2592 tsec2->create_sid = tsec1->create_sid;
2593 tsec2->keycreate_sid = tsec1->keycreate_sid;
2594 tsec2->sockcreate_sid = tsec1->sockcreate_sid;
2580 2595
2581 /* Retain ptracer SID across fork, if any. 2596 /* Retain ptracer SID across fork, if any.
2582 This will be reset by the ptrace hook upon any 2597 This will be reset by the ptrace hook upon any
@@ -2926,12 +2941,14 @@ static int selinux_socket_create(int family, int type,
2926{ 2941{
2927 int err = 0; 2942 int err = 0;
2928 struct task_security_struct *tsec; 2943 struct task_security_struct *tsec;
2944 u32 newsid;
2929 2945
2930 if (kern) 2946 if (kern)
2931 goto out; 2947 goto out;
2932 2948
2933 tsec = current->security; 2949 tsec = current->security;
2934 err = avc_has_perm(tsec->sid, tsec->sid, 2950 newsid = tsec->sockcreate_sid ? : tsec->sid;
2951 err = avc_has_perm(tsec->sid, newsid,
2935 socket_type_to_security_class(family, type, 2952 socket_type_to_security_class(family, type,
2936 protocol), SOCKET__CREATE, NULL); 2953 protocol), SOCKET__CREATE, NULL);
2937 2954
@@ -2944,12 +2961,14 @@ static void selinux_socket_post_create(struct socket *sock, int family,
2944{ 2961{
2945 struct inode_security_struct *isec; 2962 struct inode_security_struct *isec;
2946 struct task_security_struct *tsec; 2963 struct task_security_struct *tsec;
2964 u32 newsid;
2947 2965
2948 isec = SOCK_INODE(sock)->i_security; 2966 isec = SOCK_INODE(sock)->i_security;
2949 2967
2950 tsec = current->security; 2968 tsec = current->security;
2969 newsid = tsec->sockcreate_sid ? : tsec->sid;
2951 isec->sclass = socket_type_to_security_class(family, type, protocol); 2970 isec->sclass = socket_type_to_security_class(family, type, protocol);
2952 isec->sid = kern ? SECINITSID_KERNEL : tsec->sid; 2971 isec->sid = kern ? SECINITSID_KERNEL : newsid;
2953 isec->initialized = 1; 2972 isec->initialized = 1;
2954 2973
2955 return; 2974 return;
@@ -4150,6 +4169,10 @@ static int selinux_getprocattr(struct task_struct *p,
4150 sid = tsec->exec_sid; 4169 sid = tsec->exec_sid;
4151 else if (!strcmp(name, "fscreate")) 4170 else if (!strcmp(name, "fscreate"))
4152 sid = tsec->create_sid; 4171 sid = tsec->create_sid;
4172 else if (!strcmp(name, "keycreate"))
4173 sid = tsec->keycreate_sid;
4174 else if (!strcmp(name, "sockcreate"))
4175 sid = tsec->sockcreate_sid;
4153 else 4176 else
4154 return -EINVAL; 4177 return -EINVAL;
4155 4178
@@ -4182,6 +4205,10 @@ static int selinux_setprocattr(struct task_struct *p,
4182 error = task_has_perm(current, p, PROCESS__SETEXEC); 4205 error = task_has_perm(current, p, PROCESS__SETEXEC);
4183 else if (!strcmp(name, "fscreate")) 4206 else if (!strcmp(name, "fscreate"))
4184 error = task_has_perm(current, p, PROCESS__SETFSCREATE); 4207 error = task_has_perm(current, p, PROCESS__SETFSCREATE);
4208 else if (!strcmp(name, "keycreate"))
4209 error = task_has_perm(current, p, PROCESS__SETKEYCREATE);
4210 else if (!strcmp(name, "sockcreate"))
4211 error = task_has_perm(current, p, PROCESS__SETSOCKCREATE);
4185 else if (!strcmp(name, "current")) 4212 else if (!strcmp(name, "current"))
4186 error = task_has_perm(current, p, PROCESS__SETCURRENT); 4213 error = task_has_perm(current, p, PROCESS__SETCURRENT);
4187 else 4214 else
@@ -4211,6 +4238,13 @@ static int selinux_setprocattr(struct task_struct *p,
4211 tsec->exec_sid = sid; 4238 tsec->exec_sid = sid;
4212 else if (!strcmp(name, "fscreate")) 4239 else if (!strcmp(name, "fscreate"))
4213 tsec->create_sid = sid; 4240 tsec->create_sid = sid;
4241 else if (!strcmp(name, "keycreate")) {
4242 error = may_create_key(sid, p);
4243 if (error)
4244 return error;
4245 tsec->keycreate_sid = sid;
4246 } else if (!strcmp(name, "sockcreate"))
4247 tsec->sockcreate_sid = sid;
4214 else if (!strcmp(name, "current")) { 4248 else if (!strcmp(name, "current")) {
4215 struct av_decision avd; 4249 struct av_decision avd;
4216 4250
@@ -4264,7 +4298,8 @@ static int selinux_setprocattr(struct task_struct *p,
4264 4298
4265#ifdef CONFIG_KEYS 4299#ifdef CONFIG_KEYS
4266 4300
4267static int selinux_key_alloc(struct key *k, struct task_struct *tsk) 4301static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
4302 unsigned long flags)
4268{ 4303{
4269 struct task_security_struct *tsec = tsk->security; 4304 struct task_security_struct *tsec = tsk->security;
4270 struct key_security_struct *ksec; 4305 struct key_security_struct *ksec;
@@ -4274,7 +4309,10 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk)
4274 return -ENOMEM; 4309 return -ENOMEM;
4275 4310
4276 ksec->obj = k; 4311 ksec->obj = k;
4277 ksec->sid = tsec->sid; 4312 if (tsec->keycreate_sid)
4313 ksec->sid = tsec->keycreate_sid;
4314 else
4315 ksec->sid = tsec->sid;
4278 k->security = ksec; 4316 k->security = ksec;
4279 4317
4280 return 0; 4318 return 0;
@@ -4513,8 +4551,10 @@ static __init int selinux_init(void)
4513 4551
4514#ifdef CONFIG_KEYS 4552#ifdef CONFIG_KEYS
4515 /* Add security information to initial keyrings */ 4553 /* Add security information to initial keyrings */
4516 security_key_alloc(&root_user_keyring, current); 4554 selinux_key_alloc(&root_user_keyring, current,
4517 security_key_alloc(&root_session_keyring, current); 4555 KEY_ALLOC_NOT_IN_QUOTA);
4556 selinux_key_alloc(&root_session_keyring, current,
4557 KEY_ALLOC_NOT_IN_QUOTA);
4518#endif 4558#endif
4519 4559
4520 return 0; 4560 return 0;