string: Remove strlcpy()
authorKees Cook <keescook@chromium.org>
Thu, 18 Jan 2024 20:31:55 +0000 (12:31 -0800)
committerKees Cook <keescook@chromium.org>
Fri, 19 Jan 2024 19:59:11 +0000 (11:59 -0800)
With all the users of strlcpy() removed[1] from the kernel, remove the
API, self-tests, and other references. Leave mentions in Documentation
(about its deprecation), and in checkpatch.pl (to help migrate host-only
tools/ usage). Long live strscpy().

Link: https://github.com/KSPP/linux/issues/89
Cc: Azeem Shaikh <azeemshaikh38@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Whitcroft <apw@canonical.com>
Cc: Joe Perches <joe@perches.com>
Cc: Dwaipayan Ray <dwaipayanray1@gmail.com>
Cc: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Cc: linux-hardening@vger.kernel.org
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
include/linux/fortify-string.h
include/linux/string.h
lib/nlattr.c
lib/string.c
lib/test_fortify/write_overflow-strlcpy-src.c [deleted file]
lib/test_fortify/write_overflow-strlcpy.c [deleted file]

index 79ef6ac4c02113e92454d94e80565b06073c4722..89a6888f2f9e502d38f09e6a1c66f0697c3d7d08 100644 (file)
@@ -214,51 +214,6 @@ __kernel_size_t __fortify_strlen(const char * const POS p)
        return ret;
 }
 
-/* Defined after fortified strlen() to reuse it. */
-extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
-/**
- * strlcpy - Copy a string into another string buffer
- *
- * @p: pointer to destination of copy
- * @q: pointer to NUL-terminated source string to copy
- * @size: maximum number of bytes to write at @p
- *
- * If strlen(@q) >= @size, the copy of @q will be truncated at
- * @size - 1 bytes. @p will always be NUL-terminated.
- *
- * Do not use this function. While FORTIFY_SOURCE tries to avoid
- * over-reads when calculating strlen(@q), it is still possible.
- * Prefer strscpy(), though note its different return values for
- * detecting truncation.
- *
- * Returns total number of bytes written to @p, including terminating NUL.
- *
- */
-__FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, size_t size)
-{
-       const size_t p_size = __member_size(p);
-       const size_t q_size = __member_size(q);
-       size_t q_len;   /* Full count of source string length. */
-       size_t len;     /* Count of characters going into destination. */
-
-       if (p_size == SIZE_MAX && q_size == SIZE_MAX)
-               return __real_strlcpy(p, q, size);
-       q_len = strlen(q);
-       len = (q_len >= size) ? size - 1 : q_len;
-       if (__builtin_constant_p(size) && __builtin_constant_p(q_len) && size) {
-               /* Write size is always larger than destination. */
-               if (len >= p_size)
-                       __write_overflow();
-       }
-       if (size) {
-               if (len >= p_size)
-                       fortify_panic(__func__);
-               __underlying_memcpy(p, q, len);
-               p[len] = '\0';
-       }
-       return q_len;
-}
-
 /* Defined after fortified strnlen() to reuse it. */
 extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy);
 /**
@@ -272,12 +227,6 @@ extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy);
  * @p buffer. The behavior is undefined if the string buffers overlap. The
  * destination @p buffer is always NUL terminated, unless it's zero-sized.
  *
- * Preferred to strlcpy() since the API doesn't require reading memory
- * from the source @q string beyond the specified @size bytes, and since
- * the return value is easier to error-check than strlcpy()'s.
- * In addition, the implementation is robust to the string changing out
- * from underneath it, unlike the current strlcpy() implementation.
- *
  * Preferred to strncpy() since it always returns a valid string, and
  * doesn't unnecessarily force the tail of the destination buffer to be
  * zero padded. If padding is desired please use strscpy_pad().
index ce137830a0b99c1f79b100b857966443199e9777..ab148d8dbfc146d2aed178b694f33506d06bfd05 100644 (file)
@@ -66,9 +66,6 @@ extern char * strcpy(char *,const char *);
 #ifndef __HAVE_ARCH_STRNCPY
 extern char * strncpy(char *,const char *, __kernel_size_t);
 #endif
-#ifndef __HAVE_ARCH_STRLCPY
-size_t strlcpy(char *, const char *, size_t);
-#endif
 #ifndef __HAVE_ARCH_STRSCPY
 ssize_t strscpy(char *, const char *, size_t);
 #endif
index dc15e7888fc1fec5747252f3ef1b3d7b5d7d5bd8..ed2ab43e1b22c0156e5d361c6bfa7eb745759232 100644 (file)
@@ -758,7 +758,7 @@ EXPORT_SYMBOL(nla_find);
  * @dstsize: Size of destination buffer.
  *
  * Copies at most dstsize - 1 bytes into the destination buffer.
- * Unlike strlcpy the destination buffer is always padded out.
+ * Unlike strscpy() the destination buffer is always padded out.
  *
  * Return:
  * * srclen - Returns @nla length (not including the trailing %NUL).
index be26623953d2e6ef96a41567ed65e5c99787b7fb..6891d15ce991c308f198659e980f9bc9d6522335 100644 (file)
@@ -103,21 +103,6 @@ char *strncpy(char *dest, const char *src, size_t count)
 EXPORT_SYMBOL(strncpy);
 #endif
 
-#ifndef __HAVE_ARCH_STRLCPY
-size_t strlcpy(char *dest, const char *src, size_t size)
-{
-       size_t ret = strlen(src);
-
-       if (size) {
-               size_t len = (ret >= size) ? size - 1 : ret;
-               __builtin_memcpy(dest, src, len);
-               dest[len] = '\0';
-       }
-       return ret;
-}
-EXPORT_SYMBOL(strlcpy);
-#endif
-
 #ifndef __HAVE_ARCH_STRSCPY
 ssize_t strscpy(char *dest, const char *src, size_t count)
 {
diff --git a/lib/test_fortify/write_overflow-strlcpy-src.c b/lib/test_fortify/write_overflow-strlcpy-src.c
deleted file mode 100644 (file)
index 91bf83e..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#define TEST   \
-       strlcpy(small, large_src, sizeof(small) + 1)
-
-#include "test_fortify.h"
diff --git a/lib/test_fortify/write_overflow-strlcpy.c b/lib/test_fortify/write_overflow-strlcpy.c
deleted file mode 100644 (file)
index 1883db7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#define TEST   \
-       strlcpy(instance.buf, large_src, sizeof(instance.buf) + 1)
-
-#include "test_fortify.h"