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

Address Sanitizer on Windows reports a buffer overflow in Halide::serialize_pipeline #8426

Open
shoaibkamil opened this issue Sep 26, 2024 · 8 comments
Labels
dev_meeting Topic to be discussed at the next dev meeting

Comments

@shoaibkamil
Copy link
Contributor

An internal Adobe user reports that running a generator executable results in a container-overflow in the serialization code. Specifically, the offending code appears to be in Halide::Internal::Serializer::serialize(class Halide::Pipeline const &, class std::vector<unsigned char, class std::allocator<unsigned char>> &) .

@steven-johnson
Copy link
Contributor

A repro case would help :-)

@abadams
Copy link
Member

abadams commented Sep 26, 2024

Some more detail on the complaint:

1>==16204==ERROR: AddressSanitizer: container-overflow on address 0x021081271820 at pc 0x7ff9c3819a86 bp 0x00f43c98a4c0 sp 0x00f43c989c50
1>WRITE of size 117776 at 0x021081271820 thread T0
1>    #0 0x7ff9c3819a85 in __asan_wrap_memmove D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\sanitizer_common\sanitizer_common_interceptors.inc:813
1>    #1 0x7ff991b286ad in std::vector<unsigned char, class std::allocator<unsigned char>>::_Insert_range<unsigned char *>(class std::_Vector_const_iterator<class std::_Vector_val<struct std::_Simple_types<unsigned char>>>, unsigned char *, unsigned char *, struct std::forward_iterator_tag) 

@abadams
Copy link
Member

abadams commented Sep 26, 2024

It looks like it has to be the insert call here:


    uint8_t *buf = builder.GetBufferPointer();
    int size = builder.GetSize();

    if (buf != nullptr && size > 0) {
        result.clear();
        result.reserve(size);
        result.insert(result.begin(), buf, buf + size);
    } else {
        user_error << "failed to serialize pipeline!\n";
    }

But I don't see what could be wrong with it. It's a bit weird to use begin() instead of end(), but the spec says those are equal for an empty container.

@shoaibkamil
Copy link
Contributor Author

shoaibkamil commented Sep 26, 2024

A repro case would help :-)

Agreed, we'll try to create one. I concur with @abadams that it's not immediately obvious what's wrong. @slomp is also looking into this.

@abadams
Copy link
Member

abadams commented Sep 28, 2024

It's likely this is a false positive. I believe in this case Halide.dll was compiled without asan, but the generator was compiled with asan, and the std::vector in question is one that was created in the generator and passed into Halide.dll to be resized and filled. When Halide resizes it, it probably doesn't set up the right asan tracking state to catch overflows.

@slomp
Copy link
Contributor

slomp commented Sep 29, 2024

This diff adds a new interface to workaround the issue.
Now, the question is: is it worth?
Halide_patch.diff.txt

@abadams
Copy link
Member

abadams commented Sep 29, 2024

I think this is just a complex case of: don't allocate memory in a dll and free it in an exe (or vice versa), because those may be separate heaps with separate settings. I know there are cases where we deliberately avoided doing this. Maybe there's some way to catch all such cases instead of playing whack-a-mole. Passing stl types by reference definitely seems problematic on windows - we could forbid that, but without testing it's going to creep back in.

The cleanest workaround I think is to change it to just return a pimpl intrusive pointer type like Halide::Buffer<uint8_t>, so that no reallocations happen in the exe, and the constructor and destructor both happen in the dll

@abadams abadams added the dev_meeting Topic to be discussed at the next dev meeting label Sep 29, 2024
@slomp
Copy link
Contributor

slomp commented Sep 29, 2024

I like the idea of returning a Halide::Buffer. We could perhaps offer a type alias for that buffer for the (de)serialization interface(s).

There may be other places where this problem is prone to happen (std::string modifications come to mind).

@alexreinking alexreinking changed the title Adress Sanitizer on Windows reports a buffer overflow in Halide::serialize_pipeline Address Sanitizer on Windows reports a buffer overflow in Halide::serialize_pipeline Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dev_meeting Topic to be discussed at the next dev meeting
Projects
None yet
Development

No branches or pull requests

4 participants