]> https://gitweb.dealii.org/ - dealii.git/commitdiff
lac/scalapack.cc: fix an out-of-bounds write that leads to a double free
authorMatthias Maier <tamiko@43-1.org>
Mon, 3 Jul 2023 01:40:44 +0000 (20:40 -0500)
committerMatthias Maier <tamiko@43-1.org>
Mon, 3 Jul 2023 16:50:13 +0000 (11:50 -0500)
```
==1080297==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x60200003da70 in thread T0
    #0 0x55bcdd907b7d in operator delete(void*) (/srv/temp/testsuite-IQZ1b8kK/build/tests/scalapack/scalapack_06b.debug/scalapack_06b.debug+0x17cb7d)
    #1 0x7fc52a4d2047 in void std::__1::__libcpp_operator_delete[abi:v160006]<void*>(void*) /usr/include/c++/v1/new:276:3
    #2 0x7fc52a4d2047 in void std::__1::__do_deallocate_handle_size[abi:v160006]<>(void*, unsigned long) /usr/include/c++/v1/new:300:10
    #3 0x7fc52a4d2047 in std::__1::__libcpp_deallocate[abi:v160006](void*, unsigned long, unsigned long) /usr/include/c++/v1/new:316:14
    #4 0x7fc52a4d2047 in std::__1::allocator<int>::deallocate[abi:v160006](int*, unsigned long) /usr/include/c++/v1/__memory/allocator.h:131:13
    #5 0x7fc52a4d2047 in std::__1::allocator_traits<std::__1::allocator<int>>::deallocate[abi:v160006](std::__1::allocator<int>&, int*, unsigned long) /usr/include/c++/v1/__memory/allocator_traits.h:288:13
    #6 0x7fc52a4d2047 in std::__1::__split_buffer<int, std::__1::allocator<int>&>::~__split_buffer() /usr/include/c++/v1/__split_buffer:362:9
    #7 0x7fc52a4d2047 in std::__1::vector<int, std::__1::allocator<int>>::__append(unsigned long) /usr/include/c++/v1/vector:1049:5
    #8 0x7fc52a8282d2 in std::__1::vector<int, std::__1::allocator<int>>::resize(unsigned long) /usr/include/c++/v1/vector:1910:15
    #9 0x7fc52a8282d2 in dealii::ScaLAPACKMatrix<double>::eigenpairs_symmetric(bool, std::__1::pair<unsigned int, unsigned int> const&, std::__1::pair<double, double> const&) /srv/temp/testsuite-IQZ1b8kK/dealii/source/lac/scalapack.cc:1684:17
    #10 0x7fc52a826813 in dealii::ScaLAPACKMatrix<double>::eigenpairs_symmetric_by_index(std::__1::pair<unsigned int, unsigned int> const&, bool) /srv/temp/testsuite-IQZ1b8kK/dealii/source/lac/scalapack.cc:1446:12
    #11 0x55bcdd911907 in void test<double>(unsigned int, unsigned int, double) /srv/temp/testsuite-IQZ1b8kK/dealii/tests/scalapack/scalapack_06b.cc:134:21
    #12 0x55bcdd90ebc8 in main /srv/temp/testsuite-IQZ1b8kK/dealii/tests/scalapack/scalapack_06b.cc:207:9
    #13 0x7fc4f5250989  (/usr/lib64/libc.so.6+0x23989)
    #14 0x7fc4f5250a44 in __libc_start_main (/usr/lib64/libc.so.6+0x23a44)
    #15 0x55bcdd7f73f0 in _start (/srv/temp/testsuite-IQZ1b8kK/build/tests/scalapack/scalapack_06b.debug/scalapack_06b.debug+0x6c3f0)
```

source/lac/scalapack.cc

index 4ef1ca0b35a6021cacd0a42b9b2d62b8147e0154..b9fb39307797325c89ee9d20385af0e3435944a9 100644 (file)
@@ -1592,8 +1592,18 @@ ScaLAPACKMatrix<NumberType>::eigenpairs_symmetric(
       int         liwork = -1;
       NumberType *eigenvectors_loc =
         (compute_eigenvectors ? eigenvectors->values.data() : nullptr);
-      work.resize(1);
-      iwork.resize(1);
+      /*
+       * According to the official "documentation" found on the internet
+       * (aka source file ppsyevx.f [1]) the work array has to have a
+       * minimal size of max(3, lwork). Because we query for optimal size
+       * (lwork == -1) we have to guarantee at least three doubles. The
+       * necessary size of iwork is not specified, so let's use three as
+       * well.
+       * [1]
+       * https://netlib.org/scalapack/explore-html/df/d1a/pdsyevx_8f_source.html
+       */
+      work.resize(3);
+      iwork.resize(3);
 
       if (all_eigenpairs)
         {

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.