summaryrefslogtreecommitdiffstats
path: root/security/keys/user_defined.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-01-17 22:09:11 +0100
committerSteve French <smfrench@gmail.com>2012-01-18 05:39:40 +0100
commit9f6ed2ca257fa8650b876377833e6f14e272848b (patch)
tree8b664dced5415a6d463a56c2bc98756bd5ea5e44 /security/keys/user_defined.c
parentcifs: lower default wsize when unix extensions are not used (diff)
downloadlinux-9f6ed2ca257fa8650b876377833e6f14e272848b.tar.xz
linux-9f6ed2ca257fa8650b876377833e6f14e272848b.zip
keys: add a "logon" key type
For CIFS, we want to be able to store NTLM credentials (aka username and password) in the keyring. We do not, however want to allow users to fetch those keys back out of the keyring since that would be a security risk. Unfortunately, due to the nuances of key permission bits, it's not possible to do this. We need to grant search permissions so the kernel can find these keys, but that also implies permissions to read the payload. Resolve this by adding a new key_type. This key type is essentially the same as key_type_user, but does not define a .read op. This prevents the payload from ever being visible from userspace. This key type also vets the description to ensure that it's "qualified" by checking to ensure that it has a ':' in it that is preceded by other characters. Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'security/keys/user_defined.c')
-rw-r--r--security/keys/user_defined.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 69ff52c08e97..6e1a6276649f 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -18,6 +18,8 @@
#include <asm/uaccess.h>
#include "internal.h"
+static int logon_vet_description(const char *desc);
+
/*
* user defined keys take an arbitrary string as the description and an
* arbitrary blob of data as the payload
@@ -36,6 +38,24 @@ struct key_type key_type_user = {
EXPORT_SYMBOL_GPL(key_type_user);
/*
+ * This key type is essentially the same as key_type_user, but it does
+ * not define a .read op. This is suitable for storing username and
+ * password pairs in the keyring that you do not want to be readable
+ * from userspace.
+ */
+struct key_type key_type_logon = {
+ .name = "logon",
+ .instantiate = user_instantiate,
+ .update = user_update,
+ .match = user_match,
+ .revoke = user_revoke,
+ .destroy = user_destroy,
+ .describe = user_describe,
+ .vet_description = logon_vet_description,
+};
+EXPORT_SYMBOL_GPL(key_type_logon);
+
+/*
* instantiate a user defined key
*/
int user_instantiate(struct key *key, const void *data, size_t datalen)
@@ -189,3 +209,20 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
}
EXPORT_SYMBOL_GPL(user_read);
+
+/* Vet the description for a "logon" key */
+static int logon_vet_description(const char *desc)
+{
+ char *p;
+
+ /* require a "qualified" description string */
+ p = strchr(desc, ':');
+ if (!p)
+ return -EINVAL;
+
+ /* also reject description with ':' as first char */
+ if (p == desc)
+ return -EINVAL;
+
+ return 0;
+}