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