|
@@ -26,6 +26,8 @@
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
#include "internal.h"
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
+#define KEY_MAX_DESC_SIZE 4096
|
|
|
|
+
|
|
static int key_get_type_from_user(char *type,
|
|
static int key_get_type_from_user(char *type,
|
|
const char __user *_type,
|
|
const char __user *_type,
|
|
unsigned len)
|
|
unsigned len)
|
|
@@ -78,7 +80,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
|
|
|
|
|
|
description = NULL;
|
|
description = NULL;
|
|
if (_description) {
|
|
if (_description) {
|
|
- description = strndup_user(_description, PAGE_SIZE);
|
|
|
|
|
|
+ description = strndup_user(_description, KEY_MAX_DESC_SIZE);
|
|
if (IS_ERR(description)) {
|
|
if (IS_ERR(description)) {
|
|
ret = PTR_ERR(description);
|
|
ret = PTR_ERR(description);
|
|
goto error;
|
|
goto error;
|
|
@@ -177,7 +179,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
|
|
goto error;
|
|
goto error;
|
|
|
|
|
|
/* pull the description into kernel space */
|
|
/* pull the description into kernel space */
|
|
- description = strndup_user(_description, PAGE_SIZE);
|
|
|
|
|
|
+ description = strndup_user(_description, KEY_MAX_DESC_SIZE);
|
|
if (IS_ERR(description)) {
|
|
if (IS_ERR(description)) {
|
|
ret = PTR_ERR(description);
|
|
ret = PTR_ERR(description);
|
|
goto error;
|
|
goto error;
|
|
@@ -287,7 +289,7 @@ long keyctl_join_session_keyring(const char __user *_name)
|
|
/* fetch the name from userspace */
|
|
/* fetch the name from userspace */
|
|
name = NULL;
|
|
name = NULL;
|
|
if (_name) {
|
|
if (_name) {
|
|
- name = strndup_user(_name, PAGE_SIZE);
|
|
|
|
|
|
+ name = strndup_user(_name, KEY_MAX_DESC_SIZE);
|
|
if (IS_ERR(name)) {
|
|
if (IS_ERR(name)) {
|
|
ret = PTR_ERR(name);
|
|
ret = PTR_ERR(name);
|
|
goto error;
|
|
goto error;
|
|
@@ -562,8 +564,9 @@ long keyctl_describe_key(key_serial_t keyid,
|
|
{
|
|
{
|
|
struct key *key, *instkey;
|
|
struct key *key, *instkey;
|
|
key_ref_t key_ref;
|
|
key_ref_t key_ref;
|
|
- char *tmpbuf;
|
|
|
|
|
|
+ char *infobuf;
|
|
long ret;
|
|
long ret;
|
|
|
|
+ int desclen, infolen;
|
|
|
|
|
|
key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW);
|
|
key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW);
|
|
if (IS_ERR(key_ref)) {
|
|
if (IS_ERR(key_ref)) {
|
|
@@ -586,38 +589,31 @@ long keyctl_describe_key(key_serial_t keyid,
|
|
}
|
|
}
|
|
|
|
|
|
okay:
|
|
okay:
|
|
- /* calculate how much description we're going to return */
|
|
|
|
- ret = -ENOMEM;
|
|
|
|
- tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
|
|
|
- if (!tmpbuf)
|
|
|
|
- goto error2;
|
|
|
|
-
|
|
|
|
key = key_ref_to_ptr(key_ref);
|
|
key = key_ref_to_ptr(key_ref);
|
|
|
|
+ desclen = strlen(key->description);
|
|
|
|
|
|
- ret = snprintf(tmpbuf, PAGE_SIZE - 1,
|
|
|
|
- "%s;%d;%d;%08x;%s",
|
|
|
|
- key->type->name,
|
|
|
|
- from_kuid_munged(current_user_ns(), key->uid),
|
|
|
|
- from_kgid_munged(current_user_ns(), key->gid),
|
|
|
|
- key->perm,
|
|
|
|
- key->description ?: "");
|
|
|
|
-
|
|
|
|
- /* include a NUL char at the end of the data */
|
|
|
|
- if (ret > PAGE_SIZE - 1)
|
|
|
|
- ret = PAGE_SIZE - 1;
|
|
|
|
- tmpbuf[ret] = 0;
|
|
|
|
- ret++;
|
|
|
|
|
|
+ /* calculate how much information we're going to return */
|
|
|
|
+ ret = -ENOMEM;
|
|
|
|
+ infobuf = kasprintf(GFP_KERNEL,
|
|
|
|
+ "%s;%d;%d;%08x;",
|
|
|
|
+ key->type->name,
|
|
|
|
+ from_kuid_munged(current_user_ns(), key->uid),
|
|
|
|
+ from_kgid_munged(current_user_ns(), key->gid),
|
|
|
|
+ key->perm);
|
|
|
|
+ if (!infobuf)
|
|
|
|
+ goto error2;
|
|
|
|
+ infolen = strlen(infobuf);
|
|
|
|
+ ret = infolen + desclen + 1;
|
|
|
|
|
|
/* consider returning the data */
|
|
/* consider returning the data */
|
|
- if (buffer && buflen > 0) {
|
|
|
|
- if (buflen > ret)
|
|
|
|
- buflen = ret;
|
|
|
|
-
|
|
|
|
- if (copy_to_user(buffer, tmpbuf, buflen) != 0)
|
|
|
|
|
|
+ if (buffer && buflen >= ret) {
|
|
|
|
+ if (copy_to_user(buffer, infobuf, infolen) != 0 ||
|
|
|
|
+ copy_to_user(buffer + infolen, key->description,
|
|
|
|
+ desclen + 1) != 0)
|
|
ret = -EFAULT;
|
|
ret = -EFAULT;
|
|
}
|
|
}
|
|
|
|
|
|
- kfree(tmpbuf);
|
|
|
|
|
|
+ kfree(infobuf);
|
|
error2:
|
|
error2:
|
|
key_ref_put(key_ref);
|
|
key_ref_put(key_ref);
|
|
error:
|
|
error:
|
|
@@ -649,7 +645,7 @@ long keyctl_keyring_search(key_serial_t ringid,
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
goto error;
|
|
goto error;
|
|
|
|
|
|
- description = strndup_user(_description, PAGE_SIZE);
|
|
|
|
|
|
+ description = strndup_user(_description, KEY_MAX_DESC_SIZE);
|
|
if (IS_ERR(description)) {
|
|
if (IS_ERR(description)) {
|
|
ret = PTR_ERR(description);
|
|
ret = PTR_ERR(description);
|
|
goto error;
|
|
goto error;
|