aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-07-04 17:25:02 +0100
committerMoyster <oysterized@gmail.com>2019-07-06 11:51:10 +0200
commitc3adf4ac17b9a3957e9feb108aedaca807389cee (patch)
tree626fdb75333b45dcaaa0328745d8942122832f42
parent71f684be4b39cc2b0576db7da67195fdd958de0a (diff)
Provide a function to create a NUL-terminated string from unterminated data
commit f35157417215ec138c920320c746fdb3e04ef1d5 upstream. Provide a function, kmemdup_nul(), that will create a NUL-terminated string from an unterminated character array where the length is known in advance. This is better than kstrndup() in situations where we already know the string length as the strnlen() in kstrndup() is superfluous. Change-Id: I52f8594090d324c4aa9530c0ad9d287ac43ac0fc Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--include/linux/string.h1
-rw-r--r--mm/util.c24
2 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/string.h b/include/linux/string.h
index 5aab1f795..acad4a055 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -119,6 +119,7 @@ char *strreplace(char *s, char old, char new);
extern char *kstrdup(const char *s, gfp_t gfp);
extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
+extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
extern void argv_free(char **argv);
diff --git a/mm/util.c b/mm/util.c
index e94408780..2f937038f 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -42,6 +42,8 @@ EXPORT_SYMBOL(kstrdup);
* @s: the string to duplicate
* @max: read at most @max chars from @s
* @gfp: the GFP mask used in the kmalloc() call when allocating memory
+ *
+ * Note: Use kmemdup_nul() instead if the size is known exactly.
*/
char *kstrndup(const char *s, size_t max, gfp_t gfp)
{
@@ -80,6 +82,28 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
EXPORT_SYMBOL(kmemdup);
/**
+ * kmemdup_nul - Create a NUL-terminated string from unterminated data
+ * @s: The data to stringify
+ * @len: The size of the data
+ * @gfp: the GFP mask used in the kmalloc() call when allocating memory
+ */
+char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
+{
+ char *buf;
+
+ if (!s)
+ return NULL;
+
+ buf = kmalloc_track_caller(len + 1, gfp);
+ if (buf) {
+ memcpy(buf, s, len);
+ buf[len] = '\0';
+ }
+ return buf;
+}
+EXPORT_SYMBOL(kmemdup_nul);
+
+/**
* memdup_user - duplicate memory region from user space
*
* @src: source address in user space