Bug 29591 - wcsnlen length can overflow in page cross case.
Summary: wcsnlen length can overflow in page cross case.
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: string (show other bugs)
Version: 2.36
: P2 normal
Target Milestone: 2.38
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-09-20 22:55 UTC by Noah Goldstein
Modified: 2023-03-01 16:46 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Fix and test cases. (1.42 KB, patch)
2022-09-20 22:58 UTC, Noah Goldstein
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Noah Goldstein 2022-09-20 22:55:36 UTC
```
#include <assert.h>
#include <stdint.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;
}

size_t __wcsnlen_avx2(wchar_t const *, size_t);
size_t __wcsnlen_evex(wchar_t const *, size_t);

int
main(int argc, char ** argv) {
    wchar_t * buf  = (wchar_t *)make_buf(PAGE_SIZE);
    wchar_t * wstr = buf + (PAGE_SIZE / sizeof(wchar_t)) - 2;

    /* Expect wstr len == 1.  */
    memset(wstr, -1, sizeof(wchar_t));
    memset(wstr + 1, 0, sizeof(wchar_t));


    assert(__wcsnlen_evex(wstr, (1UL << 63)) == 1);
    assert(__wcsnlen_avx2(wstr, (1UL << 63)) == 1);
}
```

Build statically so `__wcsnlen_avx2` / `__wcsnlen_evex` are defined.


Output:
```
wcsnlen: wcsnlen.c:31: main: Assertion `__wcsnlen_avx2(wstr, (1UL << 63)) == 1' failed.
Aborted (core dumped)
```
Comment 1 Noah Goldstein 2022-09-20 22:58:54 UTC
Created attachment 14340 [details]
Fix and test cases.

Fix, will post once all tests complete.
Comment 2 Carlos O'Donell 2023-03-01 16:45:01 UTC
Fixed in master, 2.37, 2.36, 2.35, 2.34, and 2.33.

commit b0969fa53a28b4ab2159806bf6c99a98999502ee
Author: Noah Goldstein <goldstein.w.n@gmail.com>
Date:   Tue Sep 20 17:58:04 2022 -0700

    x86: Fix wcsnlen-avx2 page cross length comparison [BZ #29591]
    
    Previous implementation was adjusting length (rsi) to match
    bytes (eax), but since there is no bound to length this can cause
    overflow.
    
    Fix is to just convert the byte-count (eax) to length by dividing by
    sizeof (wchar_t) before the comparison.
    
    Full check passes on x86-64 and build succeeds w/ and w/o multiarch.
Comment 3 Carlos O'Donell 2023-03-01 16:46:36 UTC
Additionally fixed in in 2.32, 2.31, 2.30, 2.29, and 2.28 to resolve ifunc backports.