Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cppcheck for openSUSE:Factory checked in at 2023-12-21 23:38:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cppcheck (Old) and /work/SRC/openSUSE:Factory/.cppcheck.new.1840 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cppcheck" Thu Dec 21 23:38:44 2023 rev:36 rq:1134347 version:2.12.1 Changes: -------- --- /work/SRC/openSUSE:Factory/cppcheck/cppcheck.changes 2023-11-13 22:24:51.316304785 +0100 +++ /work/SRC/openSUSE:Factory/.cppcheck.new.1840/cppcheck.changes 2023-12-21 23:38:56.403252835 +0100 @@ -1,0 +2,5 @@ +Wed Dec 20 23:14:07 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- add CVE-2023-39070.patch (CVE-2023-39070, bsc#1215233) + +------------------------------------------------------------------- New: ---- CVE-2023-39070.patch BETA DEBUG BEGIN: New: - add CVE-2023-39070.patch (CVE-2023-39070, bsc#1215233) BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cppcheck.spec ++++++ --- /var/tmp/diff_new_pack.TJRq6M/_old 2023-12-21 23:38:57.131279420 +0100 +++ /var/tmp/diff_new_pack.TJRq6M/_new 2023-12-21 23:38:57.135279565 +0100 @@ -25,6 +25,7 @@ Source: https://github.com/danmar/cppcheck/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz Patch0: eb076d87.patch Patch1: werror-return-type.patch +Patch2: CVE-2023-39070.patch BuildRequires: cmake BuildRequires: docbook-xsl-stylesheets BuildRequires: fdupes ++++++ CVE-2023-39070.patch ++++++ >From 76695f6be2685a1ee7436e563bc550eab506952a Mon Sep 17 00:00:00 2001 From: Dirk Mueller <dmuel...@suse.com> Date: Tue, 19 Dec 2023 20:44:22 +0100 Subject: [PATCH] Fix #12272 (removeContradiction() Avoid use-after-free on multiple remove) (#5707) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As reported in https://sourceforge.net/p/cppcheck/discussion/general/thread/fa43fb8ab1/ removeContradiction() minValue/maxValue.remove(..) can access free'd memory as it removes all matching values by iterating over the complete list. Creating a full copy instead of a reference avoids this issue. Signed-off-by: Dirk Müller <d...@dmllr.de> --- lib/preprocessor.cpp | 16 +++++++----- lib/token.cpp | 60 +++++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 34 deletions(-) Index: cppcheck-2.12.1/lib/token.cpp =================================================================== --- cppcheck-2.12.1.orig/lib/token.cpp +++ cppcheck-2.12.1/lib/token.cpp @@ -1955,64 +1955,68 @@ static bool isAdjacent(const ValueFlow:: return std::abs(x.intvalue - y.intvalue) == 1; } -static bool removePointValue(std::list<ValueFlow::Value>& values, ValueFlow::Value& x) +static bool removePointValue(std::list<ValueFlow::Value>& values, std::list<ValueFlow::Value>::iterator& x) { - const bool isPoint = x.bound == ValueFlow::Value::Bound::Point; + const bool isPoint = x->bound == ValueFlow::Value::Bound::Point; if (!isPoint) - x.decreaseRange(); + x->decreaseRange(); else - values.remove(x); + x = values.erase(x); return isPoint; } static bool removeContradiction(std::list<ValueFlow::Value>& values) { bool result = false; - for (ValueFlow::Value& x : values) { - if (x.isNonValue()) + for (auto itx = values.begin(); itx != values.end(); ++itx) { + if (itx->isNonValue()) continue; - for (ValueFlow::Value& y : values) { - if (y.isNonValue()) + + auto ity = itx; + ++ity; + for (; ity != values.end(); ++ity) { + if (ity->isNonValue()) continue; - if (x == y) + if (*itx == *ity) continue; - if (x.valueType != y.valueType) + if (itx->valueType != ity->valueType) continue; - if (x.isImpossible() == y.isImpossible()) + if (itx->isImpossible() == ity->isImpossible()) continue; - if (x.isSymbolicValue() && !ValueFlow::Value::sameToken(x.tokvalue, y.tokvalue)) + if (itx->isSymbolicValue() && !ValueFlow::Value::sameToken(itx->tokvalue, ity->tokvalue)) continue; - if (!x.equalValue(y)) { - auto compare = [](const ValueFlow::Value& x, const ValueFlow::Value& y) { - return x.compareValue(y, less{}); + if (!itx->equalValue(*ity)) { + auto compare = [](const std::list<ValueFlow::Value>::const_iterator& x, const std::list<ValueFlow::Value>::const_iterator& y) { + return x->compareValue(*y, less{}); }; - const ValueFlow::Value& maxValue = std::max(x, y, compare); - const ValueFlow::Value& minValue = std::min(x, y, compare); + auto itMax = std::max(itx, ity, compare); + auto itMin = std::min(itx, ity, compare); // TODO: Adjust non-points instead of removing them - if (maxValue.isImpossible() && maxValue.bound == ValueFlow::Value::Bound::Upper) { - values.remove(minValue); + if (itMax->isImpossible() && itMax->bound == ValueFlow::Value::Bound::Upper) { + values.erase(itMin); return true; } - if (minValue.isImpossible() && minValue.bound == ValueFlow::Value::Bound::Lower) { - values.remove(maxValue); + if (itMin->isImpossible() && itMin->bound == ValueFlow::Value::Bound::Lower) { + values.erase(itMax); return true; } continue; } - const bool removex = !x.isImpossible() || y.isKnown(); - const bool removey = !y.isImpossible() || x.isKnown(); - if (x.bound == y.bound) { + const bool removex = !itx->isImpossible() || ity->isKnown(); + const bool removey = !ity->isImpossible() || itx->isKnown(); + if (itx->bound == ity->bound) { if (removex) - values.remove(x); + values.erase(itx); if (removey) - values.remove(y); + values.erase(ity); + // itx and ity are invalidated return true; } result = removex || removey; bool bail = false; - if (removex && removePointValue(values, x)) + if (removex && removePointValue(values, itx)) bail = true; - if (removey && removePointValue(values, y)) + if (removey && removePointValue(values, ity)) bail = true; if (bail) return true;