[PATCH 0/2] strndup_user, v3

From: Davi Arnaut
Date: Sat Feb 18 2006 - 08:34:19 EST


Andrew,

This patch series creates a strndup_user() function in order to avoid duplicated
and error-prone (userspace modifying the string after the strlen_user()) code.

v3: Removed strdup_user in favor of only strndup_user.

I hope to have addressed all concerns.

The diffstat:

include/linux/string.h | 2
kernel/module.c | 19 +-------
mm/util.c | 37 +++++++++++++++
security/keys/keyctl.c | 116 ++++++++++---------------------------------------
4 files changed, 67 insertions(+), 107 deletions(-)

Signed-off-by: Davi Arnaut <davi.arnaut@xxxxxxxxx>
--

diff --git a/include/linux/string.h b/include/linux/string.h
index 369be32..dee2214 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -18,6 +18,8 @@ extern char * strsep(char **,const char
extern __kernel_size_t strspn(const char *,const char *);
extern __kernel_size_t strcspn(const char *,const char *);

+extern char *strndup_user(const char __user *, long);
+
/*
* Include machine specific inline routines
*/
diff --git a/mm/util.c b/mm/util.c
index 5f4bb59..49e29f7 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -1,6 +1,8 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/uaccess.h>

/**
* kzalloc - allocate memory. The memory is set to zero.
@@ -37,3 +39,38 @@ char *kstrdup(const char *s, gfp_t gfp)
return buf;
}
EXPORT_SYMBOL(kstrdup);
+
+/*
+ * strndup_user - duplicate an existing string from user space
+ *
+ * @s: The string to duplicate
+ * @n: Maximum number of bytes to copy, including the trailing NUL.
+ */
+char *strndup_user(const char __user *s, long n)
+{
+ char *p;
+ long length;
+
+ length = strnlen_user(s, n);
+
+ if (!length)
+ return ERR_PTR(-EFAULT);
+
+ if (length > n)
+ return ERR_PTR(-EINVAL);
+
+ p = kmalloc(length, GFP_KERNEL);
+
+ if (!p)
+ return ERR_PTR(-ENOMEM);
+
+ if (copy_from_user(p, s, length)) {
+ kfree(p);
+ return ERR_PTR(-EFAULT);
+ }
+
+ p[length - 1] = '\0';
+
+ return p;
+}
+EXPORT_SYMBOL(strndup_user);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/