Skip to content

Commit f478898

Browse files
committed
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 <[email protected]> Cc: Andrew Morton <[email protected]> Cc: <[email protected]> Reviewed-by: Justin Stitt <[email protected]> Signed-off-by: Kees Cook <[email protected]>
1 parent 557f8c5 commit f478898

File tree

2 files changed

+31
-36
lines changed

2 files changed

+31
-36
lines changed

include/linux/string.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,37 @@ extern char * strncpy(char *,const char *, __kernel_size_t);
7070
ssize_t strscpy(char *, const char *, size_t);
7171
#endif
7272

73-
/* Wraps calls to strscpy()/memset(), no arch specific code required */
74-
ssize_t strscpy_pad(char *dest, const char *src, size_t count);
73+
/**
74+
* strscpy_pad() - Copy a C-string into a sized buffer
75+
* @dest: Where to copy the string to
76+
* @src: Where to copy the string from
77+
* @count: Size of destination buffer
78+
*
79+
* Copy the string, or as much of it as fits, into the dest buffer. The
80+
* behavior is undefined if the string buffers overlap. The destination
81+
* buffer is always %NUL terminated, unless it's zero-sized.
82+
*
83+
* If the source string is shorter than the destination buffer, the
84+
* remaining bytes in the buffer will be filled with %NUL bytes.
85+
*
86+
* For full explanation of why you may want to consider using the
87+
* 'strscpy' functions please see the function docstring for strscpy().
88+
*
89+
* Returns:
90+
* * The number of characters copied (not including the trailing %NULs)
91+
* * -E2BIG if count is 0 or @src was truncated.
92+
*/
93+
#define strscpy_pad(dest, src, count) ({ \
94+
char *__dst = (dest); \
95+
const char *__src = (src); \
96+
const size_t __count = (count); \
97+
ssize_t __wrote; \
98+
\
99+
__wrote = strscpy(__dst, __src, __count); \
100+
if (__wrote >= 0 && __wrote < __count) \
101+
memset(__dst + __wrote + 1, 0, __count - __wrote - 1); \
102+
__wrote; \
103+
})
75104

76105
#ifndef __HAVE_ARCH_STRCAT
77106
extern char * strcat(char *, const char *);

lib/string_helpers.c

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -825,40 +825,6 @@ char **devm_kasprintf_strarray(struct device *dev, const char *prefix, size_t n)
825825
}
826826
EXPORT_SYMBOL_GPL(devm_kasprintf_strarray);
827827

828-
/**
829-
* strscpy_pad() - Copy a C-string into a sized buffer
830-
* @dest: Where to copy the string to
831-
* @src: Where to copy the string from
832-
* @count: Size of destination buffer
833-
*
834-
* Copy the string, or as much of it as fits, into the dest buffer. The
835-
* behavior is undefined if the string buffers overlap. The destination
836-
* buffer is always %NUL terminated, unless it's zero-sized.
837-
*
838-
* If the source string is shorter than the destination buffer, zeros
839-
* the tail of the destination buffer.
840-
*
841-
* For full explanation of why you may want to consider using the
842-
* 'strscpy' functions please see the function docstring for strscpy().
843-
*
844-
* Returns:
845-
* * The number of characters copied (not including the trailing %NUL)
846-
* * -E2BIG if count is 0 or @src was truncated.
847-
*/
848-
ssize_t strscpy_pad(char *dest, const char *src, size_t count)
849-
{
850-
ssize_t written;
851-
852-
written = strscpy(dest, src, count);
853-
if (written < 0 || written == count - 1)
854-
return written;
855-
856-
memset(dest + written + 1, 0, count - written - 1);
857-
858-
return written;
859-
}
860-
EXPORT_SYMBOL(strscpy_pad);
861-
862828
/**
863829
* skip_spaces - Removes leading whitespace from @str.
864830
* @str: The string to be stripped.

0 commit comments

Comments
 (0)