Skip to content

Commit 458a3bf

Browse files
Tobin C. HardingShuah Khan
authored andcommitted
lib/string: Add strscpy_pad() function
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 <[email protected]> Signed-off-by: Tobin C. Harding <[email protected]> Signed-off-by: Shuah Khan <[email protected]>
1 parent 6b1a4d5 commit 458a3bf

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

include/linux/string.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ size_t strlcpy(char *, const char *, size_t);
3131
#ifndef __HAVE_ARCH_STRSCPY
3232
ssize_t strscpy(char *, const char *, size_t);
3333
#endif
34+
35+
/* Wraps calls to strscpy()/memset(), no arch specific code required */
36+
ssize_t strscpy_pad(char *dest, const char *src, size_t count);
37+
3438
#ifndef __HAVE_ARCH_STRCAT
3539
extern char * strcat(char *, const char *);
3640
#endif

lib/string.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,9 @@ EXPORT_SYMBOL(strlcpy);
159159
* @src: Where to copy the string from
160160
* @count: Size of destination buffer
161161
*
162-
* Copy the string, or as much of it as fits, into the dest buffer.
163-
* The routine returns the number of characters copied (not including
164-
* the trailing NUL) or -E2BIG if the destination buffer wasn't big enough.
165-
* The behavior is undefined if the string buffers overlap.
166-
* The destination buffer is always NUL terminated, unless it's zero-sized.
162+
* Copy the string, or as much of it as fits, into the dest buffer. The
163+
* behavior is undefined if the string buffers overlap. The destination
164+
* buffer is always NUL terminated, unless it's zero-sized.
167165
*
168166
* Preferred to strlcpy() since the API doesn't require reading memory
169167
* from the src string beyond the specified "count" bytes, and since
@@ -173,8 +171,10 @@ EXPORT_SYMBOL(strlcpy);
173171
*
174172
* Preferred to strncpy() since it always returns a valid string, and
175173
* doesn't unnecessarily force the tail of the destination buffer to be
176-
* zeroed. If the zeroing is desired, it's likely cleaner to use strscpy()
177-
* with an overflow test, then just memset() the tail of the dest buffer.
174+
* zeroed. If zeroing is desired please use strscpy_pad().
175+
*
176+
* Return: The number of characters copied (not including the trailing
177+
* %NUL) or -E2BIG if the destination buffer wasn't big enough.
178178
*/
179179
ssize_t strscpy(char *dest, const char *src, size_t count)
180180
{
@@ -237,6 +237,39 @@ ssize_t strscpy(char *dest, const char *src, size_t count)
237237
EXPORT_SYMBOL(strscpy);
238238
#endif
239239

240+
/**
241+
* strscpy_pad() - Copy a C-string into a sized buffer
242+
* @dest: Where to copy the string to
243+
* @src: Where to copy the string from
244+
* @count: Size of destination buffer
245+
*
246+
* Copy the string, or as much of it as fits, into the dest buffer. The
247+
* behavior is undefined if the string buffers overlap. The destination
248+
* buffer is always %NUL terminated, unless it's zero-sized.
249+
*
250+
* If the source string is shorter than the destination buffer, zeros
251+
* the tail of the destination buffer.
252+
*
253+
* For full explanation of why you may want to consider using the
254+
* 'strscpy' functions please see the function docstring for strscpy().
255+
*
256+
* Return: The number of characters copied (not including the trailing
257+
* %NUL) or -E2BIG if the destination buffer wasn't big enough.
258+
*/
259+
ssize_t strscpy_pad(char *dest, const char *src, size_t count)
260+
{
261+
ssize_t written;
262+
263+
written = strscpy(dest, src, count);
264+
if (written < 0 || written == count - 1)
265+
return written;
266+
267+
memset(dest + written + 1, 0, count - written - 1);
268+
269+
return written;
270+
}
271+
EXPORT_SYMBOL(strscpy_pad);
272+
240273
#ifndef __HAVE_ARCH_STRCAT
241274
/**
242275
* strcat - Append one %NUL-terminated string to another

0 commit comments

Comments
 (0)