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:
+31
-2
@@ -70,8 +70,37 @@ extern char * strncpy(char *,const char *, __kernel_size_t);
|
||||
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);
|
||||
/**
|
||||
* 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
|
||||
extern char * strcat(char *, const char *);
|
||||
|
||||
Reference in New Issue
Block a user