libgeos / geos

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

Stack Overflow in coordinate.h #1070

Open gabe-sherman opened 1 month ago

gabe-sherman commented 1 month ago

A stack overflow occurs in the below program when provided with malformed input. This behavior occurs at line 355 in coordinate.h

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

static void GEOSMessageHandlerfp(const char *fmt, ...){
exit(0);
}
int main(int argc, char *argv[])
{
    FILE *f;
    char *fuzzData = NULL;
    char *fuzzDataCmp = 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);
    fuzzDataCmp = (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';
    strcpy(fuzzDataCmp, fuzzData);

   double GEOSLengthvar0 = 2.0;
   initGEOS(GEOSMessageHandlerfp, GEOSMessageHandlerfp);
   GEOSWKTReader* GEOSWKTReader_createval1 = GEOSWKTReader_create();
    if(!GEOSWKTReader_createval1){
        fprintf(stderr, "err");
    }
   GEOSGeometry* GEOSWKTReader_readval1 = GEOSWKTReader_read(GEOSWKTReader_createval1, fuzzData);
    if(strcmp(fuzzDataCmp, fuzzData)){
        fprintf(stderr, "err");
    }
    if(!GEOSWKTReader_readval1){
        fprintf(stderr, "err");
    }

   int GEOSLengthval1 = GEOSLength(GEOSWKTReader_readval1, &GEOSLengthvar0);
    if(GEOSLengthval1 < 0){
        fprintf(stderr, "err");
    }
   GEOSGeometry* GEOSTopologyPreserveSimplifyval1 = GEOSTopologyPreserveSimplify(GEOSWKTReader_readval1, GEOSLengthvar0);
    if(!GEOSTopologyPreserveSimplifyval1){
        fprintf(stderr, "err");
    }
   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-01

Address Sanitizer Output

==272065==ERROR: AddressSanitizer: stack-overflow on address 0x7fffff7fefd8 (pc 0x55555591fca6 bp 0x7fffff7ff810 sp 0x7fffff7fefe0 T0)
    #0 0x55555591fca6 in __asan_memcpy (/home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/bin/geosop+0x3cbca6) (BuildId: f49253123649c26420b5c36a7e096573a65ecee3)
    #1 0x555555adc667 in geos::geom::CoordinateXYZM::CoordinateXYZM(geos::geom::Coordinate const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/include/geos/geom/Coordinate.h:355:11
    #2 0x555555adc667 in geos::geom::CoordinateXYZM geos::algorithm::LineIntersector::zmGetOrInterpolateCopy<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/include/geos/algorithm/LineIntersector.h:640:30
    #3 0x555555adbec8 in unsigned char geos::algorithm::LineIntersector::computeCollinearIntersection<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/include/geos/algorithm/LineIntersector.h:489:24
    #4 0x555555adb890 in unsigned char geos::algorithm::LineIntersector::computeIntersect<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/include/geos/algorithm/LineIntersector.h:371:20
    #5 0x555555adb387 in void geos::algorithm::LineIntersector::computeIntersection<geos::geom::Coordinate, geos::geom::Coordinate>(geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&, geos::geom::Coordinate const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/include/geos/algorithm/LineIntersector.h:168:18
    #6 0x555555e91fef in geos::simplify::TaggedLineStringSimplifier::hasInvalidIntersection(geos::geom::LineSegment const&, geos::geom::LineSegment const&) const /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/simplify/TaggedLineStringSimplifier.cpp:279:9
    #7 0x555555e919cc in geos::simplify::TaggedLineStringSimplifier::hasOutputIntersection(geos::geom::LineSegment const&) /home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/src/simplify/TaggedLineStringSimplifier.cpp:263:12

... a bunch of the same  geos::simplify::TaggedLineStringSimplifier::hasOutputIntersection messages ...

SUMMARY: AddressSanitizer: stack-overflow (/home/gabesherman/harness_test/AutoHarn-Evaluation/geos/lib_asan/bin/geosop+0x3cbca6) (BuildId: f49253123649c26420b5c36a7e096573a65ecee3) in __asan_memcpy
==272065==ABORTING
gabe-sherman commented 1 month ago

Hey quick update, we actually have a more simple reproducer for this crash. Executing geosop -a poc simplifyTP 2.0 results in the execution of the same bug.