Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<ranges>: Access violation on find in byte range with unreachable_sentinel #2431

Closed
AlexGuteniev opened this issue Dec 18, 2021 · 1 comment · Fixed by #2434
Closed

<ranges>: Access violation on find in byte range with unreachable_sentinel #2431

AlexGuteniev opened this issue Dec 18, 2021 · 1 comment · Fixed by #2434
Labels
bug Something isn't working fixed Something works now, yay! ranges C++20/23 ranges

Comments

@AlexGuteniev
Copy link
Contributor

AlexGuteniev commented Dec 18, 2021

Describe the bug
ranges::find with unreachable_sentinel may read beyond the found element.
This is due to memchr optimization and memchr misbehavior reported as DevCom-1615707

Command-line test case

#include <cassert>
#include <ranges>
#include <utility>

#include <Windows.h>

using namespace std;

void* volatile discard;

int main() {
    SYSTEM_INFO si = {};
    GetSystemInfo(&si);

    const size_t page  = si.dwPageSize;
    const size_t alloc = max<size_t>(page * 2, si.dwAllocationGranularity);

    void* p = VirtualAlloc(nullptr, alloc, MEM_RESERVE, PAGE_NOACCESS);
    assert(p != nullptr);
    void* p2 = VirtualAlloc(p, page, MEM_COMMIT, PAGE_READWRITE);
    assert(p2 != nullptr);

    const auto p3    = reinterpret_cast<char*>(p2) + page - 3;
    p3[0]            = '1';
    p3[1]            = '2';
    p3[2]            = '3';
    const auto bingo = ranges::find(p3, unreachable_sentinel, '3');
    assert(bingo == p3 + 2);

    const auto bingo2 = ranges::find(p3 - 16, unreachable_sentinel, '2');
    assert(bingo2 == p3 + 1);

    const auto bingo3 = ranges::find(p3 - 32, unreachable_sentinel, '1');
    assert(bingo3 == p3);

    const auto bingo4 = ranges::find(p3 - 64, unreachable_sentinel, '3');
    assert(bingo4 == p3 + 2);

    VirtualFree(p, 0, MEM_RELEASE);
}

Expected behavior
No crash. But still with optimization of this case.

STL version
Version 17.1.0 Preview 1.1

Additional context
Relates to #2379 - in scope of this improvement can also address this problem

AlexGuteniev added a commit to AlexGuteniev/STL that referenced this issue Dec 18, 2021
New vector search to resolve microsoft#2379 and test that it fixes microsoft#2431 find
@CaseyCarter CaseyCarter added bug Something isn't working ranges C++20/23 ranges labels Dec 18, 2021
@AlexGuteniev
Copy link
Contributor Author

Need to know if ARM / ARM64 versions are also affected or not to make the right fix.

@StephanTLavavej StephanTLavavej added the fixed Something works now, yay! label Apr 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed Something works now, yay! ranges C++20/23 ranges
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants