string: Redefine strscpy_pad() as a macro
In preparation for making strscpy_pad()'s 3rd argument optional, redefine it as a macro. This also has the benefit of allowing greater FORITFY introspection, as it couldn't see into the strscpy() nor the memset() within strscpy_pad(). Cc: Andy Shevchenko <andy@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: <linux-hardening@vger.kernel.org> Reviewed-by: Justin Stitt <justinstitt@google.com> Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
557f8c582a
commit
f478898e0a
|
@ -70,8 +70,37 @@ extern char * strncpy(char *,const char *, __kernel_size_t);
|
||||||
ssize_t strscpy(char *, const char *, size_t);
|
ssize_t strscpy(char *, const char *, size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Wraps calls to strscpy()/memset(), no arch specific code required */
|
/**
|
||||||
ssize_t strscpy_pad(char *dest, const char *src, size_t count);
|
* 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, the
|
||||||
|
* remaining bytes in the buffer will be filled with %NUL bytes.
|
||||||
|
*
|
||||||
|
* For full explanation of why you may want to consider using the
|
||||||
|
* 'strscpy' functions please see the function docstring for strscpy().
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* * The number of characters copied (not including the trailing %NULs)
|
||||||
|
* * -E2BIG if count is 0 or @src was truncated.
|
||||||
|
*/
|
||||||
|
#define strscpy_pad(dest, src, count) ({ \
|
||||||
|
char *__dst = (dest); \
|
||||||
|
const char *__src = (src); \
|
||||||
|
const size_t __count = (count); \
|
||||||
|
ssize_t __wrote; \
|
||||||
|
\
|
||||||
|
__wrote = strscpy(__dst, __src, __count); \
|
||||||
|
if (__wrote >= 0 && __wrote < __count) \
|
||||||
|
memset(__dst + __wrote + 1, 0, __count - __wrote - 1); \
|
||||||
|
__wrote; \
|
||||||
|
})
|
||||||
|
|
||||||
#ifndef __HAVE_ARCH_STRCAT
|
#ifndef __HAVE_ARCH_STRCAT
|
||||||
extern char * strcat(char *, const char *);
|
extern char * strcat(char *, const char *);
|
||||||
|
|
|
@ -825,40 +825,6 @@ char **devm_kasprintf_strarray(struct device *dev, const char *prefix, size_t n)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_kasprintf_strarray);
|
EXPORT_SYMBOL_GPL(devm_kasprintf_strarray);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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().
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* * The number of characters copied (not including the trailing %NUL)
|
|
||||||
* * -E2BIG if count is 0 or @src was truncated.
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* skip_spaces - Removes leading whitespace from @str.
|
* skip_spaces - Removes leading whitespace from @str.
|
||||||
* @str: The string to be stripped.
|
* @str: The string to be stripped.
|
||||||
|
|
Loading…
Reference in New Issue