Re: [PATCH v3] lib/string.c: implement stpcpy

From: Kees Cook
Date: Wed Aug 26 2020 - 11:22:30 EST


On Tue, Aug 25, 2020 at 07:00:00AM -0700, Nick Desaulniers wrote:
> 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 it
> returns the pointer to the new tail of `dest`. This optimization was
> introduced into clang-12.
>
> 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")
>
> The kernel is somewhere between a "freestanding" environment (no full libc)
> and "hosted" environment (many symbols from libc exist with the same
> type, function signature, and semantics).
>
> As H. Peter Anvin notes, there's not really a great way to inform the
> compiler that you're targeting a freestanding environment but would like
> to opt-in to some libcall optimizations (see pr/47280 below), rather than
> opt-out.
>
> Arvind notes, -fno-builtin-* behaves slightly differently between GCC
> and Clang, and Clang is missing many __builtin_* definitions, which I
> consider a bug in Clang and am working on fixing.
>
> Masahiro summarizes the subtle distinction between compilers justly:
> To prevent transformation from foo() into bar(), there are two ways in
> Clang to do that; -fno-builtin-foo, and -fno-builtin-bar. There is
> only one in GCC; -fno-buitin-foo.
>
> (Any difference in that behavior in Clang is likely a bug from a missing
> __builtin_* definition.)
>
> Masahiro also notes:
> We want to disable optimization from foo() to bar(),
> but we may still benefit from the optimization from
> foo() into something else. If GCC implements the same transform, we
> would run into a problem because it is not -fno-builtin-bar, but
> -fno-builtin-foo that disables that optimization.
>
> In this regard, -fno-builtin-foo would be more future-proof than
> -fno-built-bar, but -fno-builtin-foo is still potentially overkill. We
> may want to prevent calls from foo() being optimized into calls to
> bar(), but we still may want other optimization on calls to foo().
>
> It seems that compilers today don't quite provide the fine grain control
> over which libcall optimizations pseudo-freestanding environments would
> prefer.
>
> Finally, Kees notes that this interface is unsafe, so we should not
> encourage its use. As such, I've removed the declaration from any
> header, but it still needs to be exported to avoid linkage errors in
> modules.
>
> Cc: stable@xxxxxxxxxxxxxxx
> Link: https://bugs.llvm.org/show_bug.cgi?id=47162
> Link: https://bugs.llvm.org/show_bug.cgi?id=47280
> 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
> Suggested-by: Andy Lavr <andy.lavr@xxxxxxxxx>
> Suggested-by: Arvind Sankar <nivedita@xxxxxxxxxxxx>
> Suggested-by: Joe Perches <joe@xxxxxxxxxxx>
> Suggested-by: Masahiro Yamada <masahiroy@xxxxxxxxxx>
> Suggested-by: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
> Reported-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx>
> Signed-off-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx>

Acked-by: Kees Cook <keescook@xxxxxxxxxxxx>

--
Kees Cook