|
@@ -19,6 +19,7 @@
|
|
|
#include <linux/capability.h>
|
|
|
#include <linux/string.h>
|
|
|
#include <linux/err.h>
|
|
|
+#include <linux/vmalloc.h>
|
|
|
#include <asm/uaccess.h>
|
|
|
#include "internal.h"
|
|
|
|
|
@@ -62,9 +63,10 @@ asmlinkage long sys_add_key(const char __user *_type,
|
|
|
char type[32], *description;
|
|
|
void *payload;
|
|
|
long ret;
|
|
|
+ bool vm;
|
|
|
|
|
|
ret = -EINVAL;
|
|
|
- if (plen > 32767)
|
|
|
+ if (plen > 1024 * 1024 - 1)
|
|
|
goto error;
|
|
|
|
|
|
/* draw all the data into kernel space */
|
|
@@ -81,11 +83,18 @@ asmlinkage long sys_add_key(const char __user *_type,
|
|
|
/* pull the payload in if one was supplied */
|
|
|
payload = NULL;
|
|
|
|
|
|
+ vm = false;
|
|
|
if (_payload) {
|
|
|
ret = -ENOMEM;
|
|
|
payload = kmalloc(plen, GFP_KERNEL);
|
|
|
- if (!payload)
|
|
|
- goto error2;
|
|
|
+ if (!payload) {
|
|
|
+ if (plen <= PAGE_SIZE)
|
|
|
+ goto error2;
|
|
|
+ vm = true;
|
|
|
+ payload = vmalloc(plen);
|
|
|
+ if (!payload)
|
|
|
+ goto error2;
|
|
|
+ }
|
|
|
|
|
|
ret = -EFAULT;
|
|
|
if (copy_from_user(payload, _payload, plen) != 0)
|
|
@@ -113,7 +122,10 @@ asmlinkage long sys_add_key(const char __user *_type,
|
|
|
|
|
|
key_ref_put(keyring_ref);
|
|
|
error3:
|
|
|
- kfree(payload);
|
|
|
+ if (!vm)
|
|
|
+ kfree(payload);
|
|
|
+ else
|
|
|
+ vfree(payload);
|
|
|
error2:
|
|
|
kfree(description);
|
|
|
error:
|
|
@@ -821,9 +833,10 @@ long keyctl_instantiate_key(key_serial_t id,
|
|
|
key_ref_t keyring_ref;
|
|
|
void *payload;
|
|
|
long ret;
|
|
|
+ bool vm = false;
|
|
|
|
|
|
ret = -EINVAL;
|
|
|
- if (plen > 32767)
|
|
|
+ if (plen > 1024 * 1024 - 1)
|
|
|
goto error;
|
|
|
|
|
|
/* the appropriate instantiation authorisation key must have been
|
|
@@ -843,8 +856,14 @@ long keyctl_instantiate_key(key_serial_t id,
|
|
|
if (_payload) {
|
|
|
ret = -ENOMEM;
|
|
|
payload = kmalloc(plen, GFP_KERNEL);
|
|
|
- if (!payload)
|
|
|
- goto error;
|
|
|
+ if (!payload) {
|
|
|
+ if (plen <= PAGE_SIZE)
|
|
|
+ goto error;
|
|
|
+ vm = true;
|
|
|
+ payload = vmalloc(plen);
|
|
|
+ if (!payload)
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
|
|
|
ret = -EFAULT;
|
|
|
if (copy_from_user(payload, _payload, plen) != 0)
|
|
@@ -877,7 +896,10 @@ long keyctl_instantiate_key(key_serial_t id,
|
|
|
}
|
|
|
|
|
|
error2:
|
|
|
- kfree(payload);
|
|
|
+ if (!vm)
|
|
|
+ kfree(payload);
|
|
|
+ else
|
|
|
+ vfree(payload);
|
|
|
error:
|
|
|
return ret;
|
|
|
|