From e8adf5d33132cf91da0b3889976fba04fd80b853 Mon Sep 17 00:00:00 2001 From: Peter Keresztes Schmidt Date: Sat, 29 May 2021 19:55:17 +0200 Subject: [PATCH 1/2] Build: Enable std::vector ASAN annotation in libstdc++ By defining _GLIBCXX_SANITIZE_VECTOR when ASAN is enabled `std::vector` operations will be annotated so ASAN can detect invalid accesses. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html --- cmake/compiler/gcc/settings.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/compiler/gcc/settings.cmake b/cmake/compiler/gcc/settings.cmake index 74fbd0b3b..638bc39b4 100644 --- a/cmake/compiler/gcc/settings.cmake +++ b/cmake/compiler/gcc/settings.cmake @@ -20,6 +20,7 @@ endif() if(ASAN) target_compile_options(zm-compile-option-interface INTERFACE + -D_GLIBCXX_SANITIZE_VECTOR=1 -fno-omit-frame-pointer -fsanitize=address -fsanitize-recover=address From 339cfd49bc35cb2b79c091f82c2c579aca318f10 Mon Sep 17 00:00:00 2001 From: Peter Keresztes Schmidt Date: Sat, 29 May 2021 19:58:19 +0200 Subject: [PATCH 2/2] Image: Remove std::vector out-of-bounds access when filling polygons While iterating through `active_edges` we call `std::next`. If the current iterator is `.end()` we are accessing out-of-bound memory. Make sure we always have a valid iterator past `it` in the loop. Follow-up on 6642ca45155a436c6208529aaffbc9f7903a720e --- src/zm_image.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 1acb49e03..60b1dcc02 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -2513,10 +2513,16 @@ void Image::Fill(Rgb colour, int density, const Polygon &polygon) { ++it; } } + + // Not enough edges to perform the fill operation. + // Continue to next line. + if (active_edges.size() < 2) { + continue; + } std::sort(active_edges.begin(), active_edges.end(), PolygonFill::Edge::CompareX); if (!(scan_line % density)) { - for (auto it = active_edges.begin(); it != active_edges.end(); ++it) { + for (auto it = active_edges.begin(); it < active_edges.end() - 1; ++it) { int32 lo_x = static_cast(it->min_x); int32 hi_x = static_cast(std::next(it)->min_x); if (colours == ZM_COLOUR_GRAY8) {