linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] lib/string.c: implement stpcpy
@ 2020-08-15  0:24 Nick Desaulniers
  2020-08-15  0:52 ` Joe Perches
                   ` (3 more replies)
  0 siblings, 4 replies; 29+ messages in thread
From: Nick Desaulniers @ 2020-08-15  0:24 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Dávid Bolvanský,
	Eli Friedman, Nick Desaulniers, stable, Sami Tolvanen,
	Joe Perches, Tony Luck, Yury Norov, Daniel Axtens, Arvind Sankar,
	Dan Williams, Joel Fernandes (Google),
	Andy Shevchenko, Kees Cook, Alexandru Ardelean, linux-kernel,
	clang-built-linux

LLVM implemented a recent "libcall optimization" that lowers calls to
`sprintf(dest, "%s", str)` where the return value is used to
`stpcpy(dest, str) - dest`. This generally avoids the machinery involved
in parsing format strings.

`stpcpy` is just like `strcpy` except:
1. it returns the pointer to the new tail of `dest`. This allows you to
   chain multiple calls to `stpcpy` in one statement.
2. it requires the parameters not to overlap.  Calling `sprintf` with
   overlapping arguments was clarified in ISO C99 and POSIX.1-2001 to be
   undefined behavior.

`stpcpy` was first standardized in POSIX.1-2008.

Implement this so that we don't observe linkage failures due to missing
symbol definitions for `stpcpy`.

Similar to last year's fire drill with:
commit 5f074f3e192f ("lib/string.c: implement a basic bcmp")

This optimization was introduced into clang-12.

Cc: stable@vger.kernel.org
Link: https://bugs.llvm.org/show_bug.cgi?id=47162
Link: https://github.com/ClangBuiltLinux/linux/issues/1126
Link: https://man7.org/linux/man-pages/man3/stpcpy.3.html
Link: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stpcpy.html
Link: https://reviews.llvm.org/D85963
Reported-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
---
 include/linux/string.h |  3 +++
 lib/string.c           | 23 +++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index b1f3894a0a3e..e570b9b10f50 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -31,6 +31,9 @@ size_t strlcpy(char *, const char *, size_t);
 #ifndef __HAVE_ARCH_STRSCPY
 ssize_t strscpy(char *, const char *, size_t);
 #endif
+#ifndef __HAVE_ARCH_STPCPY
+extern char *stpcpy(char *__restrict, const char *__restrict__);
+#endif
 
 /* Wraps calls to strscpy()/memset(), no arch specific code required */
 ssize_t strscpy_pad(char *dest, const char *src, size_t count);
diff --git a/lib/string.c b/lib/string.c
index 6012c385fb31..81bc4d62c256 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -272,6 +272,29 @@ ssize_t strscpy_pad(char *dest, const char *src, size_t count)
 }
 EXPORT_SYMBOL(strscpy_pad);
 
+#ifndef __HAVE_ARCH_STPCPY
+/**
+ * stpcpy - copy a string from src to dest returning a pointer to the new end
+ *          of dest, including src's NULL terminator. May overrun dest.
+ * @dest: pointer to end of string being copied into. Must be large enough
+ *        to receive copy.
+ * @src: pointer to the beginning of string being copied from. Must not overlap
+ *       dest.
+ *
+ * stpcpy differs from strcpy in two key ways:
+ * 1. inputs must not overlap.
+ * 2. return value is the new NULL terminated character. (for strcpy, the
+ *    return value is a pointer to src.
+ */
+#undef stpcpy
+char *stpcpy(char *__restrict__ dest, const char *__restrict__ src)
+{
+	while ((*dest++ = *src++) != '\0')
+		/* nothing */;
+	return dest;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRCAT
 /**
  * strcat - Append one %NUL-terminated string to another
-- 
2.28.0.220.ged08abb693-goog


^ permalink raw reply related	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2020-08-18  8:32 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-15  0:24 [PATCH] lib/string.c: implement stpcpy Nick Desaulniers
2020-08-15  0:52 ` Joe Perches
2020-08-15  2:00   ` Nick Desaulniers
2020-08-15  0:53 ` Sami Tolvanen
2020-08-15  1:33 ` Arvind Sankar
2020-08-15  1:40   ` Arvind Sankar
2020-08-15  2:09     ` [PATCH v2] " Nick Desaulniers
2020-08-15  2:58       ` Arvind Sankar
2020-08-15  3:42       ` Joe Perches
2020-08-15 16:34       ` Kees Cook
2020-08-15 17:38         ` Dávid Bolvanský
2020-08-15 20:47         ` Nick Desaulniers
2020-08-15 21:23           ` Joe Perches
2020-08-15 21:27             ` Dávid Bolvanský
2020-08-15 21:28             ` Nick Desaulniers
2020-08-15 21:31               ` Joe Perches
2020-08-15 22:17                 ` Nick Desaulniers
2020-08-16  0:19                   ` Fangrui Song
2020-08-16  5:22                     ` Sedat Dilek
2020-08-16 15:02                       ` Arvind Sankar
2020-08-17 17:14                         ` Sami Tolvanen
2020-08-17 18:36                           ` Nick Desaulniers
2020-08-17 19:15                             ` Kees Cook
2020-08-17 20:13                             ` Arvind Sankar
2020-08-17 21:45                               ` Nick Desaulniers
     [not found]                             ` <77557c29286140dea726cc334b4f59fc@AcuMS.aculab.com>
2020-08-18  8:32                               ` Joe Perches
2020-08-17 19:16                           ` Kees Cook
2020-08-15  2:00   ` [PATCH] " Nick Desaulniers
2020-08-15 22:17 ` David Laight

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).