diff --git a/include/linux/string.h b/include/linux/string.h index c7047ba0bc..f7284452ee 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -39,6 +39,9 @@ extern char * strcat(char *, const char *); #ifndef __HAVE_ARCH_STRNCAT extern char * strncat(char *, const char *, __kernel_size_t); #endif +#ifndef __HAVE_ARCH_STRLCAT +extern size_t strlcat(char *, const char *, __kernel_size_t); +#endif #ifndef __HAVE_ARCH_STRCMP extern int strcmp(const char *,const char *); #endif @@ -80,6 +83,9 @@ extern void * memset(void *,int,__kernel_size_t); #ifndef __HAVE_ARCH_MEMCPY extern void * memcpy(void *,const void *,__kernel_size_t); #endif +#ifndef __HAVE_ARCH_MEMSCPY +extern size_t memscpy(void *dest, size_t dst_size, const void *src, size_t copy_size); +#endif #ifndef __HAVE_ARCH_MEMMOVE extern void * memmove(void *,const void *,__kernel_size_t); #endif diff --git a/lib/string.c b/lib/string.c index 87c9a408e6..233adeeec3 100644 --- a/lib/string.c +++ b/lib/string.c @@ -175,6 +175,33 @@ char * strncat(char *dest, const char *src, size_t count) } #endif +#ifndef __HAVE_ARCH_STRLCAT +/** + * strlcat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @count: The size of the destination buffer. + * + */ +size_t strlcat(char *dest, const char *src, size_t count) +{ + size_t dsize = strlen(dest); + size_t len = strlen(src); + size_t res = dsize + len; + + /* This would be a bug */ + BUG_ON(dsize >= count); + + dest += dsize; + count -= dsize; + if (len >= count) + len = count-1; + memcpy(dest, src, len); + dest[len] = 0; + return res; +} +#endif + #ifndef __HAVE_ARCH_STRCMP /** * strcmp - Compare two strings @@ -520,6 +547,31 @@ void * memcpy(void *dest, const void *src, size_t count) } #endif +#ifndef __HAVE_ARCH_MEMSCPY +/** + * memscpy - Copy one area of memory to another + * @dest: Where to copy to + * @src: Where to copy from + * @dst_size: The size of destination buffer area + * @copy_size: The size of source buffer area + * + * You should not use this function where memcpy + * was used to copy null terminated buffer, the + * replacement function is strlcpy() and strlcat() + * depending on situation. + * + * The aim of memscpy() is to prevent buffer overflow + * by taking both destination buffer size and source + * buffer size. + */ +size_t memscpy(void *dest, size_t dst_size, const void *src, size_t copy_size) +{ + size_t min_size = dst_size < copy_size ? dst_size : copy_size; + memcpy(dest, src, min_size); + return min_size; +} +#endif + #ifndef __HAVE_ARCH_MEMMOVE /** * memmove - Copy one area of memory to another