aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/string.h3
-rw-r--r--mm/util.c38
2 files changed, 41 insertions, 0 deletions
diff --git a/include/linux/string.h b/include/linux/string.h
index b9bc9a5d9e21..e40099e585c9 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -112,7 +112,10 @@ extern void * memchr(const void *,int,__kernel_size_t);
112#endif 112#endif
113void *memchr_inv(const void *s, int c, size_t n); 113void *memchr_inv(const void *s, int c, size_t n);
114 114
115extern void kfree_const(const void *x);
116
115extern char *kstrdup(const char *s, gfp_t gfp); 117extern char *kstrdup(const char *s, gfp_t gfp);
118extern const char *kstrdup_const(const char *s, gfp_t gfp);
116extern char *kstrndup(const char *s, size_t len, gfp_t gfp); 119extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
117extern void *kmemdup(const void *src, size_t len, gfp_t gfp); 120extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
118 121
diff --git a/mm/util.c b/mm/util.c
index f3ef639c4857..3981ae9d1b15 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -12,10 +12,30 @@
12#include <linux/hugetlb.h> 12#include <linux/hugetlb.h>
13#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
14 14
15#include <asm/sections.h>
15#include <asm/uaccess.h> 16#include <asm/uaccess.h>
16 17
17#include "internal.h" 18#include "internal.h"
18 19
20static inline int is_kernel_rodata(unsigned long addr)
21{
22 return addr >= (unsigned long)__start_rodata &&
23 addr < (unsigned long)__end_rodata;
24}
25
26/**
27 * kfree_const - conditionally free memory
28 * @x: pointer to the memory
29 *
30 * Function calls kfree only if @x is not in .rodata section.
31 */
32void kfree_const(const void *x)
33{
34 if (!is_kernel_rodata((unsigned long)x))
35 kfree(x);
36}
37EXPORT_SYMBOL(kfree_const);
38
19/** 39/**
20 * kstrdup - allocate space for and copy an existing string 40 * kstrdup - allocate space for and copy an existing string
21 * @s: the string to duplicate 41 * @s: the string to duplicate
@@ -38,6 +58,24 @@ char *kstrdup(const char *s, gfp_t gfp)
38EXPORT_SYMBOL(kstrdup); 58EXPORT_SYMBOL(kstrdup);
39 59
40/** 60/**
61 * kstrdup_const - conditionally duplicate an existing const string
62 * @s: the string to duplicate
63 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
64 *
65 * Function returns source string if it is in .rodata section otherwise it
66 * fallbacks to kstrdup.
67 * Strings allocated by kstrdup_const should be freed by kfree_const.
68 */
69const char *kstrdup_const(const char *s, gfp_t gfp)
70{
71 if (is_kernel_rodata((unsigned long)s))
72 return s;
73
74 return kstrdup(s, gfp);
75}
76EXPORT_SYMBOL(kstrdup_const);
77
78/**
41 * kstrndup - allocate space for and copy an existing string 79 * kstrndup - allocate space for and copy an existing string
42 * @s: the string to duplicate 80 * @s: the string to duplicate
43 * @max: read at most @max chars from @s 81 * @max: read at most @max chars from @s