diff options
| author | David Howells <dhowells@redhat.com> | 2008-04-29 04:01:19 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 11:06:16 -0400 |
| commit | 38bbca6b6f164e08a4a9cdfd719fff679af98375 (patch) | |
| tree | c4d4839e57bbcbae1ecfa7867b810c6203b0d601 /security | |
| parent | 4220b7fe89f8c0623e09168ab81dd0da2fdadd72 (diff) | |
keys: increase the payload size when instantiating a key
Increase the size of a payload that can be used to instantiate a key in
add_key() and keyctl_instantiate_key(). This permits huge CIFS SPNEGO blobs
to be passed around. The limit is raised to 1MB. If kmalloc() can't allocate
a buffer of sufficient size, vmalloc() will be tried instead.
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Paul Moore <paul.moore@hp.com>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: James Morris <jmorris@namei.org>
Cc: Kevin Coffman <kwc@citi.umich.edu>
Cc: Steven French <sfrench@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security')
| -rw-r--r-- | security/keys/keyctl.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index d9ca15c109cc..8ec84326a983 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/capability.h> | 19 | #include <linux/capability.h> |
| 20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
| 21 | #include <linux/err.h> | 21 | #include <linux/err.h> |
| 22 | #include <linux/vmalloc.h> | ||
| 22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
| 23 | #include "internal.h" | 24 | #include "internal.h" |
| 24 | 25 | ||
| @@ -62,9 +63,10 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
| 62 | char type[32], *description; | 63 | char type[32], *description; |
| 63 | void *payload; | 64 | void *payload; |
| 64 | long ret; | 65 | long ret; |
| 66 | bool vm; | ||
| 65 | 67 | ||
| 66 | ret = -EINVAL; | 68 | ret = -EINVAL; |
| 67 | if (plen > 32767) | 69 | if (plen > 1024 * 1024 - 1) |
| 68 | goto error; | 70 | goto error; |
| 69 | 71 | ||
| 70 | /* draw all the data into kernel space */ | 72 | /* draw all the data into kernel space */ |
| @@ -81,11 +83,18 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
| 81 | /* pull the payload in if one was supplied */ | 83 | /* pull the payload in if one was supplied */ |
| 82 | payload = NULL; | 84 | payload = NULL; |
| 83 | 85 | ||
| 86 | vm = false; | ||
| 84 | if (_payload) { | 87 | if (_payload) { |
| 85 | ret = -ENOMEM; | 88 | ret = -ENOMEM; |
| 86 | payload = kmalloc(plen, GFP_KERNEL); | 89 | payload = kmalloc(plen, GFP_KERNEL); |
| 87 | if (!payload) | 90 | if (!payload) { |
| 88 | goto error2; | 91 | if (plen <= PAGE_SIZE) |
| 92 | goto error2; | ||
| 93 | vm = true; | ||
| 94 | payload = vmalloc(plen); | ||
| 95 | if (!payload) | ||
| 96 | goto error2; | ||
| 97 | } | ||
| 89 | 98 | ||
| 90 | ret = -EFAULT; | 99 | ret = -EFAULT; |
| 91 | if (copy_from_user(payload, _payload, plen) != 0) | 100 | if (copy_from_user(payload, _payload, plen) != 0) |
| @@ -113,7 +122,10 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
| 113 | 122 | ||
| 114 | key_ref_put(keyring_ref); | 123 | key_ref_put(keyring_ref); |
| 115 | error3: | 124 | error3: |
| 116 | kfree(payload); | 125 | if (!vm) |
| 126 | kfree(payload); | ||
| 127 | else | ||
| 128 | vfree(payload); | ||
| 117 | error2: | 129 | error2: |
| 118 | kfree(description); | 130 | kfree(description); |
| 119 | error: | 131 | error: |
| @@ -821,9 +833,10 @@ long keyctl_instantiate_key(key_serial_t id, | |||
| 821 | key_ref_t keyring_ref; | 833 | key_ref_t keyring_ref; |
| 822 | void *payload; | 834 | void *payload; |
| 823 | long ret; | 835 | long ret; |
| 836 | bool vm = false; | ||
| 824 | 837 | ||
| 825 | ret = -EINVAL; | 838 | ret = -EINVAL; |
| 826 | if (plen > 32767) | 839 | if (plen > 1024 * 1024 - 1) |
| 827 | goto error; | 840 | goto error; |
| 828 | 841 | ||
| 829 | /* the appropriate instantiation authorisation key must have been | 842 | /* the appropriate instantiation authorisation key must have been |
| @@ -843,8 +856,14 @@ long keyctl_instantiate_key(key_serial_t id, | |||
| 843 | if (_payload) { | 856 | if (_payload) { |
| 844 | ret = -ENOMEM; | 857 | ret = -ENOMEM; |
| 845 | payload = kmalloc(plen, GFP_KERNEL); | 858 | payload = kmalloc(plen, GFP_KERNEL); |
| 846 | if (!payload) | 859 | if (!payload) { |
| 847 | goto error; | 860 | if (plen <= PAGE_SIZE) |
| 861 | goto error; | ||
| 862 | vm = true; | ||
| 863 | payload = vmalloc(plen); | ||
| 864 | if (!payload) | ||
| 865 | goto error; | ||
| 866 | } | ||
| 848 | 867 | ||
| 849 | ret = -EFAULT; | 868 | ret = -EFAULT; |
| 850 | if (copy_from_user(payload, _payload, plen) != 0) | 869 | if (copy_from_user(payload, _payload, plen) != 0) |
| @@ -877,7 +896,10 @@ long keyctl_instantiate_key(key_serial_t id, | |||
| 877 | } | 896 | } |
| 878 | 897 | ||
| 879 | error2: | 898 | error2: |
| 880 | kfree(payload); | 899 | if (!vm) |
| 900 | kfree(payload); | ||
| 901 | else | ||
| 902 | vfree(payload); | ||
| 881 | error: | 903 | error: |
| 882 | return ret; | 904 | return ret; |
| 883 | 905 | ||
