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

Clean up an invalid memory access in makeCSR() #463

Merged

Conversation

Infinoid
Copy link
Contributor

The pointer variant of makeCSR() can read past the end of the pos array. In some (rare, unlucky) cases, this can cause the program to segfault.

The issue is that TypedComponentRef::getAsIndex does two 64-bit reads (of a 128-bit union type) and then passes (by value) down to the accessor method. The solution is to pass a reference instead, so the accessor method only does a 32-bit read, and does not touch the other memory locations.

I also added a test case that carefully arranges memory to guarantee that out-of-bounds accesses will segfault.

Fixes: #455

Here's what valgrind says before the patch was applied:

valgrind --track-origins=yes ./test
==1009579== Memcheck, a memory error detector
==1009579== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1009579== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==1009579== Command: ./test
==1009579== 
==1009579== Invalid read of size 8
==1009579==    at 0x4F736E7: taco::TypedComponentRef::getAsIndex() const (typed_value.cpp:370)
==1009579==    by 0x4F6630B: taco::Index::getSize() const (index.cpp:59)
==1009579==    by 0x10BDB9: taco::TensorBase taco::makeCSR<double>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<int, std::allocator<int> > const&, int*, int*, double*, taco::Array::Policy) (tensor.h:760)
==1009579==    by 0x10A531: main (test.cpp:26)
==1009579==  Address 0x56a0fb8 is 4 bytes after a block of size 4 alloc'd
==1009579==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==1009579==    by 0x4F4BECF: taco::makeArray(taco::Datatype, unsigned long) (array.cpp:217)
==1009579==    by 0x4D07BF9: taco::Array taco::makeArray<int>(std::vector<int, std::allocator<int> > const&) (array.h:72)
==1009579==    by 0x4CFA756: taco::Array taco::makeArray<int>(std::initializer_list<int> const&) (array.h:80)
==1009579==    by 0x4F668C3: taco::makeCSRIndex(unsigned long, int*, int*) (index.cpp:110)
==1009579==    by 0x10BDA1: taco::TensorBase taco::makeCSR<double>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<int, std::allocator<int> > const&, int*, int*, double*, taco::Array::Policy) (tensor.h:758)
==1009579==    by 0x10A531: main (test.cpp:26)
==1009579== 
==1009579== Invalid read of size 8
==1009579==    at 0x4F736E4: taco::TypedComponentRef::getAsIndex() const (typed_value.cpp:370)
==1009579==    by 0x4F663E0: taco::Index::getSize() const (index.cpp:61)
==1009579==    by 0x10BDB9: taco::TensorBase taco::makeCSR<double>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<int, std::allocator<int> > const&, int*, int*, double*, taco::Array::Policy) (tensor.h:760)
==1009579==    by 0x10A531: main (test.cpp:26)
==1009579==  Address 0x50efffc is in a rw- anonymous segment
==1009579== 
==1009579== 
==1009579== Process terminating with default action of signal 11 (SIGSEGV)
==1009579==  Bad permissions for mapped region at address 0x50F0000
==1009579==    at 0x4F736E4: taco::TypedComponentRef::getAsIndex() const (typed_value.cpp:370)
==1009579==    by 0x4F663E0: taco::Index::getSize() const (index.cpp:61)
==1009579==    by 0x10BDB9: taco::TensorBase taco::makeCSR<double>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<int, std::allocator<int> > const&, int*, int*, double*, taco::Array::Policy) (tensor.h:760)
==1009579==    by 0x10A531: main (test.cpp:26)
==1009579== 
==1009579== HEAP SUMMARY:
==1009579==     in use at exit: 28,432 bytes in 113 blocks
==1009579==   total heap usage: 364 allocs, 251 frees, 139,157 bytes allocated

And after applying the patch:

valgrind --track-origins=yes ./test
==1010084== Memcheck, a memory error detector
==1010084== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1010084== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==1010084== Command: ./test
==1010084== 
==1010084== 
==1010084== HEAP SUMMARY:
==1010084==     in use at exit: 128 bytes in 1 blocks
==1010084==   total heap usage: 370 allocs, 369 frees, 139,293 bytes allocated

@stephenchouca stephenchouca merged commit ad13006 into tensor-compiler:master May 20, 2021
@Infinoid Infinoid deleted the clean-up-makecsr-access branch May 21, 2021 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

makeCSR reads past the end of user-provided buffers
2 participants