aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/keys/keyctl.c38
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
879error2: 898error2:
880 kfree(payload); 899 if (!vm)
900 kfree(payload);
901 else
902 vfree(payload);
881error: 903error:
882 return ret; 904 return ret;
883 905