|
@@ -1099,6 +1099,17 @@ static int may_create(struct inode *dir,
|
|
FILESYSTEM__ASSOCIATE, &ad);
|
|
FILESYSTEM__ASSOCIATE, &ad);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Check whether a task can create a key. */
|
|
|
|
+static int may_create_key(u32 ksid,
|
|
|
|
+ struct task_struct *ctx)
|
|
|
|
+{
|
|
|
|
+ struct task_security_struct *tsec;
|
|
|
|
+
|
|
|
|
+ tsec = ctx->security;
|
|
|
|
+
|
|
|
|
+ return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
#define MAY_LINK 0
|
|
#define MAY_LINK 0
|
|
#define MAY_UNLINK 1
|
|
#define MAY_UNLINK 1
|
|
#define MAY_RMDIR 2
|
|
#define MAY_RMDIR 2
|
|
@@ -4150,6 +4161,8 @@ static int selinux_getprocattr(struct task_struct *p,
|
|
sid = tsec->exec_sid;
|
|
sid = tsec->exec_sid;
|
|
else if (!strcmp(name, "fscreate"))
|
|
else if (!strcmp(name, "fscreate"))
|
|
sid = tsec->create_sid;
|
|
sid = tsec->create_sid;
|
|
|
|
+ else if (!strcmp(name, "keycreate"))
|
|
|
|
+ sid = tsec->keycreate_sid;
|
|
else
|
|
else
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
@@ -4182,6 +4195,8 @@ static int selinux_setprocattr(struct task_struct *p,
|
|
error = task_has_perm(current, p, PROCESS__SETEXEC);
|
|
error = task_has_perm(current, p, PROCESS__SETEXEC);
|
|
else if (!strcmp(name, "fscreate"))
|
|
else if (!strcmp(name, "fscreate"))
|
|
error = task_has_perm(current, p, PROCESS__SETFSCREATE);
|
|
error = task_has_perm(current, p, PROCESS__SETFSCREATE);
|
|
|
|
+ else if (!strcmp(name, "keycreate"))
|
|
|
|
+ error = task_has_perm(current, p, PROCESS__SETKEYCREATE);
|
|
else if (!strcmp(name, "current"))
|
|
else if (!strcmp(name, "current"))
|
|
error = task_has_perm(current, p, PROCESS__SETCURRENT);
|
|
error = task_has_perm(current, p, PROCESS__SETCURRENT);
|
|
else
|
|
else
|
|
@@ -4211,7 +4226,12 @@ static int selinux_setprocattr(struct task_struct *p,
|
|
tsec->exec_sid = sid;
|
|
tsec->exec_sid = sid;
|
|
else if (!strcmp(name, "fscreate"))
|
|
else if (!strcmp(name, "fscreate"))
|
|
tsec->create_sid = sid;
|
|
tsec->create_sid = sid;
|
|
- else if (!strcmp(name, "current")) {
|
|
|
|
|
|
+ else if (!strcmp(name, "keycreate")) {
|
|
|
|
+ error = may_create_key(sid, p);
|
|
|
|
+ if (error)
|
|
|
|
+ return error;
|
|
|
|
+ tsec->keycreate_sid = sid;
|
|
|
|
+ } else if (!strcmp(name, "current")) {
|
|
struct av_decision avd;
|
|
struct av_decision avd;
|
|
|
|
|
|
if (sid == 0)
|
|
if (sid == 0)
|
|
@@ -4275,7 +4295,10 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
ksec->obj = k;
|
|
ksec->obj = k;
|
|
- ksec->sid = tsec->sid;
|
|
|
|
|
|
+ if (tsec->keycreate_sid)
|
|
|
|
+ ksec->sid = tsec->keycreate_sid;
|
|
|
|
+ else
|
|
|
|
+ ksec->sid = tsec->sid;
|
|
k->security = ksec;
|
|
k->security = ksec;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -4514,10 +4537,10 @@ static __init int selinux_init(void)
|
|
|
|
|
|
#ifdef CONFIG_KEYS
|
|
#ifdef CONFIG_KEYS
|
|
/* Add security information to initial keyrings */
|
|
/* Add security information to initial keyrings */
|
|
- security_key_alloc(&root_user_keyring, current,
|
|
|
|
- KEY_ALLOC_NOT_IN_QUOTA);
|
|
|
|
- security_key_alloc(&root_session_keyring, current,
|
|
|
|
- KEY_ALLOC_NOT_IN_QUOTA);
|
|
|
|
|
|
+ selinux_key_alloc(&root_user_keyring, current,
|
|
|
|
+ KEY_ALLOC_NOT_IN_QUOTA);
|
|
|
|
+ selinux_key_alloc(&root_session_keyring, current,
|
|
|
|
+ KEY_ALLOC_NOT_IN_QUOTA);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
return 0;
|
|
return 0;
|