lkml.org 
[lkml]   [2011]   [Jun]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] lib: introduce strdup_from_user
    Date
    Add function strdup_from_user(), which kmallocs a block of memory and
    copies a user-space NULL-terminated string into it. NULL is returned if
    the string is too large or cannot be accessed.

    This function is added to lib/string_helpers.c, so this file is repurposed
    to store generic "string helper" functions, and not just a function to
    assist in sprintfs.

    Signed-off-by: Timur Tabi <timur@freescale.com>
    ---
    include/linux/string_helpers.h | 2 +
    lib/string_helpers.c | 43 +++++++++++++++++++++++++++++++++++++++-
    2 files changed, 44 insertions(+), 1 deletions(-)

    diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
    index a3eb2f6..6231838 100644
    --- a/include/linux/string_helpers.h
    +++ b/include/linux/string_helpers.h
    @@ -13,4 +13,6 @@ enum string_size_units {
    int string_get_size(u64 size, enum string_size_units units,
    char *buf, int len);

    +char *strdup_from_user(const char __user *ustr, size_t max);
    +
    #endif
    diff --git a/lib/string_helpers.c b/lib/string_helpers.c
    index ab431d4..61323e6 100644
    --- a/lib/string_helpers.c
    +++ b/lib/string_helpers.c
    @@ -1,13 +1,19 @@
    /*
    - * Helpers for formatting and printing strings
    + * Additional arch-independent string helper functions
    *
    * Copyright 31 August 2008 James Bottomley
    + * Copyright (C) 2011 Freescale Semiconductor, Inc.
    + *
    */
    #include <linux/kernel.h>
    #include <linux/math64.h>
    #include <linux/module.h>
    #include <linux/string_helpers.h>

    +#include <linux/slab.h>
    +#include <linux/err.h>
    +#include <asm/uaccess.h>
    +
    /**
    * string_get_size - get the size in the specified units
    * @size: The size to be converted
    @@ -66,3 +72,38 @@ int string_get_size(u64 size, const enum string_size_units units,
    return 0;
    }
    EXPORT_SYMBOL(string_get_size);
    +
    +/**
    + * strdup_from_user - copy a user-space string to a kmalloc'd buffer
    + * @ustr: user-space pointer to null-terminated string
    + * @max: maximum size the string is allowed to be, include NULL terminator
    + *
    + * This function allocates a block of memory (using kmalloc) and copies a
    + * user-space string into that buffer. It returns a pointer to that string,
    + * or an error code.
    + */
    +char *strdup_from_user(const char __user *ustr, size_t max)
    +{
    + size_t len;
    + char *str;
    +
    + len = strnlen_user(ustr, max);
    + if (len >= max)
    + return ERR_PTR(-ENAMETOOLONG);
    +
    + /* strnlen_user returns 0 on access error */
    + if (!len)
    + return ERR_PTR(-EFAULT);
    +
    + str = kzalloc(len, GFP_KERNEL);
    + if (!str)
    + return ERR_PTR(-ENOMEM);
    +
    + if (copy_from_user(str, ustr, len)) {
    + kfree(str);
    + return ERR_PTR(-EFAULT);
    + }
    +
    + return str;
    +}
    +EXPORT_SYMBOL(strdup_from_user);
    --
    1.7.3.4



    \
     
     \ /
      Last update: 2011-06-03 18:49    [W:0.026 / U:30.252 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site