libgeos / geos

Geometry Engine, Open Source
https://libgeos.org
GNU Lesser General Public License v2.1
1.1k stars 339 forks source link

Segmentation fault in Centroid.cpp #1073

Closed gabe-sherman closed 1 month ago

gabe-sherman commented 1 month ago

A segmentation fault occurs in the below program when provided with malformed input. This behavior occurs in Centroid.cpp

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <geos_c.h>

static void geos_message_handler(const char* fmt, ...){
    va_list ap;
    va_start(ap, fmt);
    vprintf (fmt, ap);
    va_end(ap);
    exit(1);
}

int main(int argc, char *argv[])
{
    FILE *f;
    char *fuzzData = NULL;
    long size;

    if(argc < 2)
        exit(0);

    f = fopen(argv[1], "rb");
    if(f == NULL)
        exit(0);

    fseek(f, 0, SEEK_END);

    size = ftell(f);
    rewind(f);

    if(size < 1) 
        exit(0);

    fuzzData = (char*)malloc((size_t)size+1);
    if(fuzzData == NULL)
        exit(0);

    if(fread(fuzzData, (size_t)size, 1, f) != 1)
        exit(0);
    fuzzData[size] = '\0';
    initGEOS(geos_message_handler, geos_message_handler);

    double GEOSLargestEmptyCirclevar0 = 2.0;
    GEOSWKTReader* GEOSWKTReader_createval1 = GEOSWKTReader_create();
    GEOSGeometry* GEOSWKTReader_readval1 = GEOSWKTReader_read(GEOSWKTReader_createval1, "GEOMETRYCOLLECTION (MULTIPOINT((0 0), (1 1)), POINT(3 4), LINESTRING(2 3, 3 4))");
    GEOSGeometry* GEOSWKTReader_readval2 = GEOSWKTReader_read(GEOSWKTReader_createval1, fuzzData);
    GEOSGeometry* GEOSDifferenceval1 = GEOSDifference(GEOSWKTReader_readval2, GEOSWKTReader_readval1);
    GEOSGeometry* GEOSLargestEmptyCircleval1 = GEOSLargestEmptyCircle(GEOSWKTReader_readval2, GEOSWKTReader_readval2, GEOSLargestEmptyCirclevar0);
    GEOSGeometry* GEOSIntersectionval1 = GEOSIntersection(GEOSLargestEmptyCircleval1, GEOSDifferenceval1);
    GEOSWKTReader_destroy(GEOSWKTReader_createval1);
    GEOSGeom_destroy(GEOSWKTReader_readval1);
    GEOSGeom_destroy(GEOSDifferenceval1);
    GEOSGeom_destroy(GEOSLargestEmptyCircleval1);
    GEOSGeom_destroy(GEOSIntersectionval1);
    fclose(f);
    free(fuzzData);
    return 0;
}

Test Environment

Ubuntu 22.04, 64bit

How to trigger

./filename poc

Version

Latest: c8b889be9e8fa22de8a34bea50fec3bb073f6898

Poc File

https://github.com/FuturesLab/POC/blob/main/geos/poc-06

Address Sanitizer Output

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1064:9: runtime error: reference binding to null pointer of type 'const __gnu_cxx::__alloc_traits<std::allocator<double>, double>::value_type' (aka 'const double')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1064:9 in 
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1064:34: runtime error: applying non-zero offset 24 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1064:34 in 
AddressSanitizer:DEADLYSIGNAL
=================================================================
==401088==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x555555cf6151 bp 0x602000000810 sp 0x7fffffffca80 T0)
==401088==The signal is caused by a READ memory access.
==401088==Hint: address points to the zero page.
    #0 0x555555cf6151 in geos::algorithm::Centroid::centroid3(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/Centroid.cpp
    #1 0x555555cf604e in geos::algorithm::Centroid::addTriangle(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, bool) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/Centroid.cpp:139:5
    #2 0x555555cf5fe8 in geos::algorithm::Centroid::addHole(geos::geom::CoordinateSequence const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/Centroid.cpp:129:9
    #3 0x555555cf5cee in geos::algorithm::Centroid::add(geos::geom::Polygon const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/Centroid.cpp:104:9
    #4 0x555555cf624a in geos::algorithm::Centroid::Centroid(geos::geom::Geometry const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/include/geos/algorithm/Centroid.h:84:9
    #5 0x555555cf4de5 in geos::algorithm::Centroid::getCentroid(geos::geom::Geometry const&, geos::geom::CoordinateXY&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/Centroid.cpp:40:14
    #6 0x555555a5d049 in geos::geom::Geometry::getCentroid(geos::geom::CoordinateXY&) const /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/geom/Geometry.cpp:198:10
    #7 0x5555559ea83c in geos::algorithm::construct::LargestEmptyCircle::createCentroidCell(geos::geom::Geometry const*) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/construct/LargestEmptyCircle.cpp:191:11
    #8 0x5555559e8a4b in geos::algorithm::construct::LargestEmptyCircle::compute() /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/construct/LargestEmptyCircle.cpp:229:25
    #9 0x5555559e8598 in geos::algorithm::construct::LargestEmptyCircle::getRadiusLine() /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/construct/LargestEmptyCircle.cpp:102:5
    #10 0x55555595837b in GEOSLargestEmptyCircle_r::$_57::operator()() const /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/capi/geos_ts_c.cpp:1359:27
    #11 0x55555595837b in _Z7executeIZ24GEOSLargestEmptyCircle_rE4$_57LDn0EEDTclfp0_EEP20GEOSContextHandle_HSOT_ /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/capi/geos_ts_c.cpp:430:16
    #12 0x55555595807d in GEOSLargestEmptyCircle_r /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/capi/geos_ts_c.cpp:1357:16
    #13 0x555555935494 in main /home/gabesherman/harness_test/AutoHarn-Results/geos/autoharn-06/harness.c:49:48
    #14 0x7ffff7029d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #15 0x7ffff7029e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #16 0x5555558775a4 in _start (/home/gabesherman/harness_test/AutoHarn-Results/geos/autoharn-06/harness+0x3235a4) (BuildId: 22684d939676e151a828642e08add9495f8b6f75)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/algorithm/Centroid.cpp in geos::algorithm::Centroid::centroid3(geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY const&, geos::geom::CoordinateXY&)
==401088==ABORTING