The patch titled Subject: lib/strscpy: remove word-at-a-time optimization. has been removed from the -mm tree. Its filename was lib-strscpy-remove-word-at-a-time-optimization.patch This patch was dropped because an updated version will be merged ------------------------------------------------------ From: Andrey Ryabinin <aryabinin@xxxxxxxxxxxxx> Subject: lib/strscpy: remove word-at-a-time optimization. strscpy() performs the word-at-a-time optimistic reads. So it may may access the memory past the end of the object, which is perfectly fine since strscpy() doesn't use that (past-the-end) data and makes sure the optimistic read won't cross a page boundary. But KASAN doesn't know anything about that so it will complain. There are several possible ways to address this issue, but none are perfect. See https://lkml.kernel.org/r/9f0a9cf6-51f7-cd1f-5dc6-6d510a7b8ec4@xxxxxxxxxxxxx It seems the best solution is to simply disable word-at-a-time optimization. My trivial testing shows that byte-at-a-time could be up to x4.3 times slower than word-at-a-time. It may seems like a lot, but it's actually ~1.2e-10 sec per symbol vs ~4.8e-10 sec per symbol on modern hardware. And we don't use strscpy() in a performance critical paths to copy large amounts of data, so it shouldn't matter anyway. Link: http://lkml.kernel.org/r/20180109163745.3692-1-aryabinin@xxxxxxxxxxxxx Fixes: 30035e45753b7 ("string: provide strscpy()") Signed-off-by: Andrey Ryabinin <aryabinin@xxxxxxxxxxxxx> Cc: Kees Cook <keescook@xxxxxxxxxxxx> Cc: Eryu Guan <eguan@xxxxxxxxxx> Cc: Alexander Potapenko <glider@xxxxxxxxxx> Cc: Chris Metcalf <metcalf@xxxxxxxxxxxx> Cc: David Laight <David.Laight@xxxxxxxxxx> Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- lib/string.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff -puN lib/string.c~lib-strscpy-remove-word-at-a-time-optimization lib/string.c --- a/lib/string.c~lib-strscpy-remove-word-at-a-time-optimization +++ a/lib/string.c @@ -29,7 +29,6 @@ #include <linux/errno.h> #include <asm/byteorder.h> -#include <asm/word-at-a-time.h> #include <asm/page.h> #ifndef __HAVE_ARCH_STRNCASECMP @@ -177,45 +176,8 @@ EXPORT_SYMBOL(strlcpy); */ ssize_t strscpy(char *dest, const char *src, size_t count) { - const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; - size_t max = count; long res = 0; - if (count == 0) - return -E2BIG; - -#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS - /* - * If src is unaligned, don't cross a page boundary, - * since we don't know if the next page is mapped. - */ - if ((long)src & (sizeof(long) - 1)) { - size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)); - if (limit < max) - max = limit; - } -#else - /* If src or dest is unaligned, don't do word-at-a-time. */ - if (((long) dest | (long) src) & (sizeof(long) - 1)) - max = 0; -#endif - - while (max >= sizeof(unsigned long)) { - unsigned long c, data; - - c = *(unsigned long *)(src+res); - if (has_zero(c, &data, &constants)) { - data = prep_zero_mask(c, data, &constants); - data = create_zero_mask(data); - *(unsigned long *)(dest+res) = c & zero_bytemask(data); - return res + find_zero(data); - } - *(unsigned long *)(dest+res) = c; - res += sizeof(unsigned long); - count -= sizeof(unsigned long); - max -= sizeof(unsigned long); - } - while (count) { char c; _ Patches currently in -mm which might be from aryabinin@xxxxxxxxxxxxx are mm-memcontrolc-try-harder-to-decrease-limit_in_bytes.patch kasan-makefile-support-llvm-style-asan-parameters.patch lib-ubsan-add-type-mismatch-handler-for-new-gcc-clang.patch lib-ubsan-remove-returns-nonnull-attribute-checks.patch lib-ubsan-remove-returns-nonnull-attribute-checks-fix.patch