* [GIT PULL] string fixes for v6.15-rc1
@ 2025-04-06 17:54 Kees Cook
2025-04-06 19:04 ` Linus Torvalds
0 siblings, 1 reply; 11+ messages in thread
From: Kees Cook @ 2025-04-06 17:54 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas,
Kees Cook, Nathan Chancellor, Peter Collingbourne,
Vincenzo Frascino, Will Deacon
Hi Linus,
Please pull this pair of string API fixes for v6.15-rc1.
Thanks!
-Kees
The following changes since commit b688f369ae0d5d25865f5441fa62e54c7d5d0de6:
compiler_types: Introduce __nonstring_array (2025-03-12 13:21:09 -0700)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git tags/hardening-v6.15-rc1-fix1
for you to fetch changes up to 48ac25ef250da7478ea54afbb1aced40c342e78d:
kasan: Add strscpy() test to trigger tag fault on arm64 (2025-04-03 10:19:26 -0700)
----------------------------------------------------------------
string fixes for v6.15-rc1
- Add wcslen() to support more Clang libcalls (Nathan Chancellor)
- Fix KASAN MTE exceptions during strscpy() (Peter Collingbourne,
Vincenzo Frascino)
----------------------------------------------------------------
Nathan Chancellor (2):
include: Move typedefs in nls.h to their own header
lib/string.c: Add wcslen()
Peter Collingbourne (1):
string: Add load_unaligned_zeropad() code path to sized_strscpy()
Vincenzo Frascino (1):
kasan: Add strscpy() test to trigger tag fault on arm64
include/linux/nls.h | 19 +------------------
include/linux/nls_types.h | 26 ++++++++++++++++++++++++++
include/linux/string.h | 2 ++
lib/string.c | 24 +++++++++++++++++++++---
mm/kasan/kasan_test_c.c | 20 ++++++++++++++++++++
5 files changed, 70 insertions(+), 21 deletions(-)
create mode 100644 include/linux/nls_types.h
--
Kees Cook
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-06 17:54 [GIT PULL] string fixes for v6.15-rc1 Kees Cook @ 2025-04-06 19:04 ` Linus Torvalds 2025-04-06 19:31 ` Linus Torvalds 2025-04-07 1:32 ` Kees Cook 0 siblings, 2 replies; 11+ messages in thread From: Linus Torvalds @ 2025-04-06 19:04 UTC (permalink / raw) To: Kees Cook Cc: linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Nathan Chancellor, Peter Collingbourne, Vincenzo Frascino, Will Deacon On Sun, 6 Apr 2025 at 10:54, Kees Cook <kees@kernel.org> wrote: > > - Add wcslen() to support more Clang libcalls (Nathan Chancellor) Oh Christ. Does clang not know how expensive function calls can be? I really think the right fix here would have been to say "don't do that", rather than make that function available. When the function implementation is the stupid version, there is *no* advantage to a function call. In user mode, if you have (a) long strings (b) you use some optimized vectorized string library (c) you don't have the problems with function calls being potentially expensive due to return prediction CPU workarounds this compiler optimization may make sense. But in the kernel, it *never* makes sense, because none of those three issues are ever true. So this change is just *stupid*. And I'm not pulling stupid code. The one-liner rto just disable an optimization that isn't an optimization is the right thing to do. And if LTO has problems with that, then LTO needs to be fixed, dammit. It's stupid without LTO, it's doubly stupid with extra "optimizations". Linus ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-06 19:04 ` Linus Torvalds @ 2025-04-06 19:31 ` Linus Torvalds 2025-04-07 1:32 ` Kees Cook 1 sibling, 0 replies; 11+ messages in thread From: Linus Torvalds @ 2025-04-06 19:31 UTC (permalink / raw) To: Kees Cook Cc: linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Nathan Chancellor, Peter Collingbourne, Vincenzo Frascino, Will Deacon On Sun, 6 Apr 2025 at 12:04, Linus Torvalds <torvalds@linux-foundation.org> wrote: > > When the function implementation is the stupid version, there is *no* > advantage to a function call. Side note: the reason we don't do -freestanding is that some functions we really *really* want the compiler to optimize away the function entirely. Things like regular 'strlen()' are commonly used on compile-time fixed strings. It needs to be dealt with by the compiler. Same goes for the basic memcpy and memset functions. So what the kernel really wants is basically "-freestanding" but with a very targeted set of functions still dealt with by the compiler - not ever because they should be turned into function calls, but because they can be simplified to some entirely different form at compile time. (There are a _couple_ of other cases, but not many: we end up having things like "constant prefix matching" patterns, where we want the compiler to not only notice that 'strlen()' on a constant string is just a compile-time constant value, but then also want to simplify 'strncmp()' or 'memcmp()' with a small constant size to basically be a much simpler thing) But we do not want the compiler to create out-of-line function calls for code that wasn't a function call to begin with. That's pretty much the exact *opposite* of what we actually want. We did try "-freestanding" at some point, because it's the obvious way to avoid the compiler messing this very basic thing up, but those "just deal with simple cases directly" are really really important. I wish there was a version of -freestanding that did that "only simplify calls" version, not the "recognize patterns and turn them into calls that didn't exist". Linus ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-06 19:04 ` Linus Torvalds 2025-04-06 19:31 ` Linus Torvalds @ 2025-04-07 1:32 ` Kees Cook 2025-04-07 2:04 ` Linus Torvalds 1 sibling, 1 reply; 11+ messages in thread From: Kees Cook @ 2025-04-07 1:32 UTC (permalink / raw) To: Linus Torvalds Cc: linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Nathan Chancellor, Peter Collingbourne, Vincenzo Frascino, Will Deacon On April 6, 2025 12:04:04 PM PDT, Linus Torvalds <torvalds@linux-foundation.org> wrote: >On Sun, 6 Apr 2025 at 10:54, Kees Cook <kees@kernel.org> wrote: >> >> - Add wcslen() to support more Clang libcalls (Nathan Chancellor) > >Oh Christ. > >Does clang not know how expensive function calls can be? > >I really think the right fix here would have been to say "don't do >that", rather than make that function available. I should have said "libcall optimizations". It's not just blindly constructing calls. This is the same kind of thing that has been heavily discussed before for bcmp() and stpcpy(). The resolution from those threads was to add the symbol, as the least of many bad options: https://lore.kernel.org/all/CAK7LNAQHj-GeqH_5WpKo7gA6qZAiX8OOxxnL1v-SNZwRHFSXQQ@mail.gmail.com/ -- Kees Cook ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-07 1:32 ` Kees Cook @ 2025-04-07 2:04 ` Linus Torvalds 2025-04-07 17:37 ` Nathan Chancellor 2025-04-07 20:23 ` David Laight 0 siblings, 2 replies; 11+ messages in thread From: Linus Torvalds @ 2025-04-07 2:04 UTC (permalink / raw) To: Kees Cook Cc: linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Nathan Chancellor, Peter Collingbourne, Vincenzo Frascino, Will Deacon On Sun, 6 Apr 2025 at 18:33, Kees Cook <kees@kernel.org> wrote: > > I should have said "libcall optimizations". It's not just blindly constructing calls. But it's *WRONG*. It's stupid. It's not an optimization, it makes things worse. > This is the same kind of thing that has been heavily discussed before for bcmp() and stpcpy() And it makes a bit more sense at least for stpcpy(), because the implementation there is basically "strlen+memcpy". Both of which we want the compiler to work on - even if we're not interested in it ever using stpcpy(). IOF, for stpcpy, there's at least a *reason* for the compiler to do it. For something like wcslen() the answer is "DON'T DO THIS". Because there is absolutely zero upside to trying to recognize this pattern, and there is real downside. See? Don't work around the compiler doing stupid things. Fix the compiler options to tell the compiler to "Don'tDoThatThen(tm)". Linus ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-07 2:04 ` Linus Torvalds @ 2025-04-07 17:37 ` Nathan Chancellor 2025-04-07 19:02 ` Linus Torvalds 2025-04-07 20:23 ` David Laight 1 sibling, 1 reply; 11+ messages in thread From: Nathan Chancellor @ 2025-04-07 17:37 UTC (permalink / raw) To: Linus Torvalds Cc: Kees Cook, linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Peter Collingbourne, Vincenzo Frascino, Will Deacon, llvm Hi Linus, On Sun, Apr 06, 2025 at 07:04:29PM -0700, Linus Torvalds wrote: > On Sun, 6 Apr 2025 at 18:33, Kees Cook <kees@kernel.org> wrote: > > > > I should have said "libcall optimizations". It's not just blindly constructing calls. > > But it's *WRONG*. > > It's stupid. It's not an optimization, it makes things worse. > > > This is the same kind of thing that has been heavily discussed before for bcmp() and stpcpy() > > And it makes a bit more sense at least for stpcpy(), because the > implementation there is basically "strlen+memcpy". Both of which we > want the compiler to work on - even if we're not interested in it ever > using stpcpy(). > > IOF, for stpcpy, there's at least a *reason* for the compiler to do it. > > For something like wcslen() the answer is "DON'T DO THIS". Because > there is absolutely zero upside to trying to recognize this pattern, > and there is real downside. > > See? > > Don't work around the compiler doing stupid things. Fix the compiler > options to tell the compiler to "Don'tDoThatThen(tm)". So I do not necessarily disagree with you in the general sense for these types of optimizations but I figured that in this case, where this optimization only gets applied twice in a single translation unit throughout the entire kernel from what I can tell, the overhead was unlikely to matter much and it felt less problematic to just add the function. If this is still genuinely unacceptable in your eyes in spite of that, so be it. I will admit I did not actually test if '-fno-builtin-wcslen' would not work with LTO when I wrote the commit message (I merely drew on the experience for bcmp() several years ago). Now that I have, it appears to, at least for the simple arm64 allmodconfig case that I tested. Looking into it, it looks like '-fno-builtin-*' started being honored properly for LTO with [1] in LLVM 10 and fixed/adjusted for inlining in [2] in LLVM 11. So would the following change be acceptable? I can draft up a commit message and send it along today if so. diff --git a/Makefile b/Makefile index 38689a0c3605..a137de124897 100644 --- a/Makefile +++ b/Makefile @@ -1057,6 +1057,10 @@ KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3) KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) KBUILD_CFLAGS-$(CONFIG_CC_STRINGOP_OVERFLOW) += $(call cc-option, -Wstringop-overflow) +# Ensure clang does not transform certain loops into calls to wcslen() after +# https://github.com/llvm/llvm-project/commit/9694844d7e36fd5e01011ab56b64f27b867aa72d +KBUILD_CFLAGS-$(call clang-min-version, 210000) += -fno-builtin-wcslen + # disable invalid "can't wrap" optimizations for signed / pointers KBUILD_CFLAGS += -fno-strict-overflow --- [1]: https://github.com/llvm/llvm-project/commit/878ab6df033d44430939c02075ee00800995dc3b [2]: https://github.com/llvm/llvm-project/commit/f9ca75f19bab639988ebbe68c81d07babd952afb Cheers, Nathan ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-07 17:37 ` Nathan Chancellor @ 2025-04-07 19:02 ` Linus Torvalds 2025-04-07 19:25 ` Nathan Chancellor 0 siblings, 1 reply; 11+ messages in thread From: Linus Torvalds @ 2025-04-07 19:02 UTC (permalink / raw) To: Nathan Chancellor Cc: Kees Cook, linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Peter Collingbourne, Vincenzo Frascino, Will Deacon, llvm On Mon, 7 Apr 2025 at 10:37, Nathan Chancellor <nathan@kernel.org> wrote: > > So would the following change be acceptable? I can draft up a commit > message and send it along today if so. Absoluterly. That's the right thing to do. > +# Ensure clang does not transform certain loops into calls to wcslen() after > +# https://github.com/llvm/llvm-project/commit/9694844d7e36fd5e01011ab56b64f27b867aa72d > +KBUILD_CFLAGS-$(call clang-min-version, 210000) += -fno-builtin-wcslen I think you could just use KBUILD_CFLAGS += $(call cc-option, -fno-builtin-wcslen) instead, and not use some version check? Linus ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-07 19:02 ` Linus Torvalds @ 2025-04-07 19:25 ` Nathan Chancellor 2025-04-07 20:25 ` Linus Torvalds 0 siblings, 1 reply; 11+ messages in thread From: Nathan Chancellor @ 2025-04-07 19:25 UTC (permalink / raw) To: Linus Torvalds Cc: Kees Cook, linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Peter Collingbourne, Vincenzo Frascino, Will Deacon, llvm On Mon, Apr 07, 2025 at 12:02:04PM -0700, Linus Torvalds wrote: > On Mon, 7 Apr 2025 at 10:37, Nathan Chancellor <nathan@kernel.org> wrote: > > +# Ensure clang does not transform certain loops into calls to wcslen() after > > +# https://github.com/llvm/llvm-project/commit/9694844d7e36fd5e01011ab56b64f27b867aa72d > > +KBUILD_CFLAGS-$(call clang-min-version, 210000) += -fno-builtin-wcslen > > I think you could just use > > KBUILD_CFLAGS += $(call cc-option, -fno-builtin-wcslen) > > instead, and not use some version check? Sure, I just figured this has not been a problem up until this point so applying it for older versions of clang should not be necessary (since the optimization that introduces it does not exist) but also not be harmful. However, I would rather not call out to the compiler since we know it is supported with all versions of clang (and GCC but it obviously does not need it) so maybe just KBUILD_CFLAGS-$(CONFIG_CC_IS_CLANG) += -fno-builtin-wcslen or ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -fno-builtin-wcslen endif or if you do want this for GCC too, unconditionally adding it should be fine too. KBUILD_CFLAGS += -fno-builtin-wcslen No strong opinion, let me know your preference and I will make it so. Cheers, Nathan ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-07 19:25 ` Nathan Chancellor @ 2025-04-07 20:25 ` Linus Torvalds 2025-04-07 21:01 ` Nathan Chancellor 0 siblings, 1 reply; 11+ messages in thread From: Linus Torvalds @ 2025-04-07 20:25 UTC (permalink / raw) To: Nathan Chancellor Cc: Kees Cook, linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Peter Collingbourne, Vincenzo Frascino, Will Deacon, llvm On Mon, 7 Apr 2025 at 12:25, Nathan Chancellor <nathan@kernel.org> wrote: > > or if you do want this for GCC too, unconditionally adding it should be > fine too. I think if unconditionally works, that's probably the best option simply because it's the simplest option. But I don't see 'wcslen' in the gcc docs, which was why I was assuming it wanted that "check if it works" thing with "$(call cc-option,...)" I don't think we need to call out the particular compiler, since the argument against using it is not compiler-specific per se. Linus ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-07 20:25 ` Linus Torvalds @ 2025-04-07 21:01 ` Nathan Chancellor 0 siblings, 0 replies; 11+ messages in thread From: Nathan Chancellor @ 2025-04-07 21:01 UTC (permalink / raw) To: Linus Torvalds Cc: Kees Cook, linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Peter Collingbourne, Vincenzo Frascino, Will Deacon, llvm On Mon, Apr 07, 2025 at 01:25:04PM -0700, Linus Torvalds wrote: > I think if unconditionally works, that's probably the best option > simply because it's the simplest option. > > But I don't see 'wcslen' in the gcc docs, which was why I was assuming > it wanted that "check if it works" thing with "$(call cc-option,...)" It appears that neither gcc nor clang warn for "invalid" libcall values to '-fno-builtin-*': $ echo 'int main(void) { return 0; }' | clang -fno-builtin-ireallydonotexist -o /dev/null -S -x c - $ echo 'int main(void) { return 0; }' | gcc -fno-builtin-ireallydonotexist -o /dev/null -S -x c - > I don't think we need to call out the particular compiler, since the > argument against using it is not compiler-specific per se. Sounds good, I will ultimately make this: # Ensure compilers do not transform certain loops into calls to wcslen() KBUILD_CFLAGS += -fno-builtin-wcslen Cheers, Nathan ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [GIT PULL] string fixes for v6.15-rc1 2025-04-07 2:04 ` Linus Torvalds 2025-04-07 17:37 ` Nathan Chancellor @ 2025-04-07 20:23 ` David Laight 1 sibling, 0 replies; 11+ messages in thread From: David Laight @ 2025-04-07 20:23 UTC (permalink / raw) To: Linus Torvalds Cc: Kees Cook, linux-kernel, Andrey Konovalov, Andy Shevchenko, Catalin Marinas, Nathan Chancellor, Peter Collingbourne, Vincenzo Frascino, Will Deacon On Sun, 6 Apr 2025 19:04:29 -0700 Linus Torvalds <torvalds@linux-foundation.org> wrote: ... > For something like wcslen() the answer is "DON'T DO THIS". Because > there is absolutely zero upside to trying to recognize this pattern, > and there is real downside. gcc also has a nasty habit of converting: for (i = 0; i < len; i++) dst[i] = src[i]; into a call to memcpy(). If I wanted a memcpy() call I'd write one - so will most people. But if 'len' is very small (may even known to be less than, say, 4) you really want the loop - which is why it was written. I've even seen (not gcc) it converted to a 'rep movsw' 'rep movsb' pair at a time when a P4 might have been a likely target cpu. The 0 to 3 byte 'rep movsb' had a setup cost of IIRC 150 clocks. David ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-04-07 21:02 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-04-06 17:54 [GIT PULL] string fixes for v6.15-rc1 Kees Cook 2025-04-06 19:04 ` Linus Torvalds 2025-04-06 19:31 ` Linus Torvalds 2025-04-07 1:32 ` Kees Cook 2025-04-07 2:04 ` Linus Torvalds 2025-04-07 17:37 ` Nathan Chancellor 2025-04-07 19:02 ` Linus Torvalds 2025-04-07 19:25 ` Nathan Chancellor 2025-04-07 20:25 ` Linus Torvalds 2025-04-07 21:01 ` Nathan Chancellor 2025-04-07 20:23 ` David Laight
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox