Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38bbca6b authored by David Howells's avatar David Howells Committed by Linus Torvalds
Browse files

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: default avatarDavid 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4220b7fe
Loading
Loading
Loading
Loading
+30 −8
Original line number Original line Diff line number Diff line
@@ -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;