aboutsummaryrefslogtreecommitdiff
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorMichael LeMay <mdlemay@epoch.ncsc.mil>2006-06-26 00:24:57 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 09:58:18 -0700
commit4eb582cf1fbd7b9e5f466e3718a59c957e75254e (patch)
tree4387e460a50efa8d46a54526d0cf0959c0e3b428 /security/selinux/hooks.c
parent06ec7be557a1259611d6093a00463c42650dc71a (diff)
[PATCH] keys: add a way to store the appropriate context for newly-created keys
Add a /proc/<pid>/attr/keycreate entry that stores the appropriate context for newly-created keys. Modify the selinux_key_alloc hook to make use of the new entry. Update the flask headers to include a new "setkeycreate" permission for processes. Update the flask headers to include a new "create" permission for keys. Use the create permission to restrict which SIDs each task can assign to newly-created keys. Add a new parameter to the security hook "security_key_alloc" to indicate whether it is being invoked by the kernel, or from userspace. If it is being invoked by the kernel, the security hook should never fail. Update the documentation to reflect these changes. Signed-off-by: Michael LeMay <mdlemay@epoch.ncsc.mil> Signed-off-by: James Morris <jmorris@namei.org> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 13384fef0d6..0d8b27513bd 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1099,6 +1099,17 @@ static int may_create(struct inode *dir,
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_UNLINK 1
#define MAY_RMDIR 2
@@ -4150,6 +4161,8 @@ static int selinux_getprocattr(struct task_struct *p,
sid = tsec->exec_sid;
else if (!strcmp(name, "fscreate"))
sid = tsec->create_sid;
+ else if (!strcmp(name, "keycreate"))
+ sid = tsec->keycreate_sid;
else
return -EINVAL;
@@ -4182,6 +4195,8 @@ static int selinux_setprocattr(struct task_struct *p,
error = task_has_perm(current, p, PROCESS__SETEXEC);
else if (!strcmp(name, "fscreate"))
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"))
error = task_has_perm(current, p, PROCESS__SETCURRENT);
else
@@ -4211,7 +4226,12 @@ static int selinux_setprocattr(struct task_struct *p,
tsec->exec_sid = sid;
else if (!strcmp(name, "fscreate"))
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;
if (sid == 0)
@@ -4275,7 +4295,10 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
return -ENOMEM;
ksec->obj = k;
- ksec->sid = tsec->sid;
+ if (tsec->keycreate_sid)
+ ksec->sid = tsec->keycreate_sid;
+ else
+ ksec->sid = tsec->sid;
k->security = ksec;
return 0;
@@ -4514,10 +4537,10 @@ static __init int selinux_init(void)
#ifdef CONFIG_KEYS
/* 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
return 0;