lkml.org 
[lkml]   [2015]   [Jan]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/5] mm/util: add kstrdup_const
    Date
    The patch adds alternative version of kstrdup which returns pointer
    to constant char array. The function checks if input string is in
    persistent and read-only memory section, if yes it returns the input string,
    otherwise it fallbacks to kstrdup.
    kstrdup_const is accompanied by kfree_const performing conditional memory
    deallocation of the string.

    Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
    ---
    include/linux/string.h | 3 +++
    mm/util.c | 38 ++++++++++++++++++++++++++++++++++++++
    2 files changed, 41 insertions(+)

    diff --git a/include/linux/string.h b/include/linux/string.h
    index 2e22a2e..b11ed1e 100644
    --- a/include/linux/string.h
    +++ b/include/linux/string.h
    @@ -115,7 +115,10 @@ extern void * memchr(const void *,int,__kernel_size_t);
    #endif
    void *memchr_inv(const void *s, int c, size_t n);

    +extern void kfree_const(const void *x);
    +
    extern char *kstrdup(const char *s, gfp_t gfp);
    +extern const char *kstrdup_const(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);

    diff --git a/mm/util.c b/mm/util.c
    index fec39d4..7c62128 100644
    --- a/mm/util.c
    +++ b/mm/util.c
    @@ -12,10 +12,30 @@
    #include <linux/hugetlb.h>
    #include <linux/vmalloc.h>

    +#include <asm/sections.h>
    #include <asm/uaccess.h>

    #include "internal.h"

    +static inline int is_kernel_rodata(unsigned long addr)
    +{
    + return addr >= (unsigned long)__start_rodata &&
    + addr < (unsigned long)__end_rodata;
    +}
    +
    +/**
    + * kfree_const - conditionally free memory
    + * @x: pointer to the memory
    + *
    + * Function calls kfree only if @x is not in .rodata section.
    + */
    +void kfree_const(const void *x)
    +{
    + if (!is_kernel_rodata((unsigned long)x))
    + kfree(x);
    +}
    +EXPORT_SYMBOL(kfree_const);
    +
    /**
    * kstrdup - allocate space for and copy an existing string
    * @s: the string to duplicate
    @@ -38,6 +58,24 @@ char *kstrdup(const char *s, gfp_t gfp)
    EXPORT_SYMBOL(kstrdup);

    /**
    + * kstrdup_const - conditionally duplicate an existing const string
    + * @s: the string to duplicate
    + * @gfp: the GFP mask used in the kmalloc() call when allocating memory
    + *
    + * Function returns source string if it is in .rodata section otherwise it
    + * fallbacks to kstrdup.
    + * Strings allocated by kstrdup_const should be freed by kfree_const.
    + */
    +const char *kstrdup_const(const char *s, gfp_t gfp)
    +{
    + if (is_kernel_rodata((unsigned long)s))
    + return s;
    +
    + return kstrdup(s, gfp);
    +}
    +EXPORT_SYMBOL(kstrdup_const);
    +
    +/**
    * kstrndup - allocate space for and copy an existing string
    * @s: the string to duplicate
    * @max: read at most @max chars from @s
    --
    1.9.1


    \
     
     \ /
      Last update: 2015-01-12 10:41    [W:5.539 / U:0.272 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site