Wrong result for strncmp-avx2 and strncmp-evex when it hits the page cross case followed by the loop page cross case immediately afterwards with a short length. See following test case: ``` #include <assert.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <wchar.h> #define PAGE_SIZE 4096 static void * make_buf(uint64_t sz) { void * p = mmap(NULL, 2 * PAGE_SIZE + sz, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); assert(p != NULL); assert(!mprotect(p + PAGE_SIZE, sz, PROT_READ | PROT_WRITE)); return p + PAGE_SIZE; } int main(int argc, char ** argv) { char * s1 = make_buf(0xd000 + 0x4000); char * s2 = make_buf(0xd000 + 0x4000); s1 += 0xffa; s2 += 0xfed; strcpy(s1, "tst-tlsmod%"); strcpy(s2, "tst-tls-manydynamic73mod"); if (strncmp(s1, s2, 10) != 0) { printf("Error!\n"); } } ``` Issue (for both evex and avx2) ``` .p2align 4,, 10 L(return_page_cross_end_check): tzcntl %ecx, %ecx ``` `ecx` can have garbabe in it from before the start of the string. Fix is to use the `r10` mask to and off these bad matches (strcmp was doing so. It was an oversight not to to do so in strncmp).
Created attachment 13979 [details] A patch to add a testcase
I have patch with test + fix. Just testing on build-many which takes a bit.
Fix has been pushed: https://sourceware.org/git/?p=glibc.git;a=commit;h=e108c02a5e23c8c88ce66d8705d4a24bb6b9a8bf
Thanks. Which commit introduced the problem? Do we need to backport this to release branches?
Commits: EVEX: https://sourceware.org/git/?p=glibc.git;a=commit;h=8418eb3ff4b781d31c4ed5dc6c0bd7356bc45db9 AVX2: https://sourceware.org/git/?p=glibc.git;a=commit;h=b77b06e0e296f1a2276c27a67e1d44f2cfa38d45 No need to backport. We waited until after 2.35 release to push.