diff options
Diffstat (limited to 'lib/string.c')
-rw-r--r-- | lib/string.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/lib/string.c b/lib/string.c index b2de45a581f4..7c0c69bb5b68 100644 --- a/lib/string.c +++ b/lib/string.c @@ -186,6 +186,7 @@ ssize_t strscpy(char *dest, const char *src, size_t count) if (count == 0 || WARN_ON_ONCE(count > INT_MAX)) return -E2BIG; +#ifndef CONFIG_DCACHE_WORD_ACCESS #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS /* * If src is unaligned, don't cross a page boundary, @@ -201,11 +202,25 @@ ssize_t strscpy(char *dest, const char *src, size_t count) if (((long) dest | (long) src) & (sizeof(long) - 1)) max = 0; #endif +#endif + + /* + * load_unaligned_zeropad() or read_word_at_a_time() below may read + * uninitialized bytes after the trailing zero and use them in + * comparisons. Disable this optimization under KMSAN to prevent + * false positive reports. + */ + if (IS_ENABLED(CONFIG_KMSAN)) + max = 0; while (max >= sizeof(unsigned long)) { unsigned long c, data; +#ifdef CONFIG_DCACHE_WORD_ACCESS + c = load_unaligned_zeropad(src+res); +#else c = read_word_at_a_time(src+res); +#endif if (has_zero(c, &data, &constants)) { data = prep_zero_mask(c, data, &constants); data = create_zero_mask(data); |