diff options
author | Eric Biggers <ebiggers@google.com> | 2017-06-08 09:48:18 -0400 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2017-06-08 23:29:46 -0400 |
commit | 794b4bc292f5d31739d89c0202c54e7dc9bc3add (patch) | |
tree | 717c0817eea7ddb40659b40f45f7524eedddc901 /security/keys | |
parent | e9ff56ac352446f55141aaef1553cee662b2e310 (diff) |
KEYS: encrypted: fix buffer overread in valid_master_desc()
With the 'encrypted' key type it was possible for userspace to provide a
data blob ending with a master key description shorter than expected,
e.g. 'keyctl add encrypted desc "new x" @s'. When validating such a
master key description, validate_master_desc() could read beyond the end
of the buffer. Fix this by using strncmp() instead of memcmp(). [Also
clean up the code to deduplicate some logic.]
Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security/keys')
-rw-r--r-- | security/keys/encrypted-keys/encrypted.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index d14f1a47a130..0f7b95de3b5f 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c | |||
@@ -141,23 +141,22 @@ static int valid_ecryptfs_desc(const char *ecryptfs_desc) | |||
141 | */ | 141 | */ |
142 | static int valid_master_desc(const char *new_desc, const char *orig_desc) | 142 | static int valid_master_desc(const char *new_desc, const char *orig_desc) |
143 | { | 143 | { |
144 | if (!memcmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) { | 144 | int prefix_len; |
145 | if (strlen(new_desc) == KEY_TRUSTED_PREFIX_LEN) | 145 | |
146 | goto out; | 146 | if (!strncmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) |
147 | if (orig_desc) | 147 | prefix_len = KEY_TRUSTED_PREFIX_LEN; |
148 | if (memcmp(new_desc, orig_desc, KEY_TRUSTED_PREFIX_LEN)) | 148 | else if (!strncmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) |
149 | goto out; | 149 | prefix_len = KEY_USER_PREFIX_LEN; |
150 | } else if (!memcmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) { | 150 | else |
151 | if (strlen(new_desc) == KEY_USER_PREFIX_LEN) | 151 | return -EINVAL; |
152 | goto out; | 152 | |
153 | if (orig_desc) | 153 | if (!new_desc[prefix_len]) |
154 | if (memcmp(new_desc, orig_desc, KEY_USER_PREFIX_LEN)) | 154 | return -EINVAL; |
155 | goto out; | 155 | |
156 | } else | 156 | if (orig_desc && strncmp(new_desc, orig_desc, prefix_len)) |
157 | goto out; | 157 | return -EINVAL; |
158 | |||
158 | return 0; | 159 | return 0; |
159 | out: | ||
160 | return -EINVAL; | ||
161 | } | 160 | } |
162 | 161 | ||
163 | /* | 162 | /* |