lkml.org 
[lkml]   [2021]   [Feb]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 16/24] lib/string: Add strscpy_pad() function
    Date
    From: Tobin C. Harding <tobin@kernel.org>

    [ Upstream commit 458a3bf82df4fe1f951d0f52b1e0c1e9d5a88a3b ]

    We have a function to copy strings safely and we have a function to copy
    strings and zero the tail of the destination (if source string is
    shorter than destination buffer) but we do not have a function to do
    both at once. This means developers must write this themselves if they
    desire this functionality. This is a chore, and also leaves us open to
    off by one errors unnecessarily.

    Add a function that calls strscpy() then memset()s the tail to zero if
    the source string is shorter than the destination buffer.

    Acked-by: Kees Cook <keescook@chromium.org>
    Signed-off-by: Tobin C. Harding <tobin@kernel.org>
    Signed-off-by: Shuah Khan <shuah@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/linux/string.h | 4 ++++
    lib/string.c | 47 +++++++++++++++++++++++++++++++++++-------
    2 files changed, 44 insertions(+), 7 deletions(-)

    diff --git a/include/linux/string.h b/include/linux/string.h
    index 4db285b83f44e..1e0c442b941e2 100644
    --- a/include/linux/string.h
    +++ b/include/linux/string.h
    @@ -31,6 +31,10 @@ size_t strlcpy(char *, const char *, size_t);
    #ifndef __HAVE_ARCH_STRSCPY
    ssize_t strscpy(char *, const char *, size_t);
    #endif
    +
    +/* Wraps calls to strscpy()/memset(), no arch specific code required */
    +ssize_t strscpy_pad(char *dest, const char *src, size_t count);
    +
    #ifndef __HAVE_ARCH_STRCAT
    extern char * strcat(char *, const char *);
    #endif
    diff --git a/lib/string.c b/lib/string.c
    index edf4907ec946f..f7f7770444bf5 100644
    --- a/lib/string.c
    +++ b/lib/string.c
    @@ -158,11 +158,9 @@ EXPORT_SYMBOL(strlcpy);
    * @src: Where to copy the string from
    * @count: Size of destination buffer
    *
    - * Copy the string, or as much of it as fits, into the dest buffer.
    - * The routine returns the number of characters copied (not including
    - * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough.
    - * The behavior is undefined if the string buffers overlap.
    - * The destination buffer is always NUL terminated, unless it's zero-sized.
    + * Copy the string, or as much of it as fits, into the dest buffer. The
    + * behavior is undefined if the string buffers overlap. The destination
    + * buffer is always NUL terminated, unless it's zero-sized.
    *
    * Preferred to strlcpy() since the API doesn't require reading memory
    * from the src string beyond the specified "count" bytes, and since
    @@ -172,8 +170,10 @@ EXPORT_SYMBOL(strlcpy);
    *
    * Preferred to strncpy() since it always returns a valid string, and
    * doesn't unnecessarily force the tail of the destination buffer to be
    - * zeroed. If the zeroing is desired, it's likely cleaner to use strscpy()
    - * with an overflow test, then just memset() the tail of the dest buffer.
    + * zeroed. If zeroing is desired please use strscpy_pad().
    + *
    + * Return: The number of characters copied (not including the trailing
    + * %NUL) or -E2BIG if the destination buffer wasn't big enough.
    */
    ssize_t strscpy(char *dest, const char *src, size_t count)
    {
    @@ -260,6 +260,39 @@ char *stpcpy(char *__restrict__ dest, const char *__restrict__ src)
    }
    EXPORT_SYMBOL(stpcpy);

    +/**
    + * strscpy_pad() - Copy a C-string into a sized buffer
    + * @dest: Where to copy the string to
    + * @src: Where to copy the string from
    + * @count: Size of destination buffer
    + *
    + * Copy the string, or as much of it as fits, into the dest buffer. The
    + * behavior is undefined if the string buffers overlap. The destination
    + * buffer is always %NUL terminated, unless it's zero-sized.
    + *
    + * If the source string is shorter than the destination buffer, zeros
    + * the tail of the destination buffer.
    + *
    + * For full explanation of why you may want to consider using the
    + * 'strscpy' functions please see the function docstring for strscpy().
    + *
    + * Return: The number of characters copied (not including the trailing
    + * %NUL) or -E2BIG if the destination buffer wasn't big enough.
    + */
    +ssize_t strscpy_pad(char *dest, const char *src, size_t count)
    +{
    + ssize_t written;
    +
    + written = strscpy(dest, src, count);
    + if (written < 0 || written == count - 1)
    + return written;
    +
    + memset(dest + written + 1, 0, count - written - 1);
    +
    + return written;
    +}
    +EXPORT_SYMBOL(strscpy_pad);
    +
    #ifndef __HAVE_ARCH_STRCAT
    /**
    * strcat - Append one %NUL-terminated string to another
    --
    2.27.0


    \
     
     \ /
      Last update: 2021-02-11 17:08    [W:4.850 / U:1.548 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site