Skip to content

v0.4.2

Latest

Choose a tag to compare

@jwinarske jwinarske released this 14 Aug 21:42
c44e741

Security and reliability fix. Recommended for all users. pana 160/160.

Undefined behavior parsing untrusted catalog data

The digit accumulators in AppStreamParser computed result * 10 + digit with no bound, so a long enough run of digits overflowed. Signed overflow is undefined behavior. UBSan confirmed it on the real code path:

AppStreamParser.cpp:57 runtime error: signed integer overflow:
  999999999999999999 * 10 cannot be represented in type 'long long int'
AppStreamParser.cpp:37 runtime error: signed integer overflow:
  999999999 * 10 cannot be represented in type 'int'

Both are reached from attribute values in a catalog downloaded over the network<release timestamp="999…"> and <icon width="999…">. The same helper also parses priority, image and video dimensions, and icon scale.

Accumulation now saturates, so a hostile value is clamped rather than wrapped, and the parse stays total. Three regression tests cover it.

This was not caught earlier despite CI running a Debug/Release x asan/ubsan matrix, because no test fed an oversized number.

Unchecked gmtime_r

gmtime_r returns null for a time_t it cannot represent, which a saturated epoch reaches. The return value was ignored, leaving the std::tm zero-initialized and silently producing a 1900-01-01T00:00:00Z timestamp. An unrepresentable epoch now yields no timestamp.

Pinned static analysis

scripts/tidy.sh pins clang-tidy the way scripts/format.sh pins clang-format, and the CI clang-tidy job is no longer advisory.

Unpinned, results depended on which LLVM happened to be first on PATH. The version CI installed could not parse a current libstdc++ — it emitted 20 parse errors and stopped early — while also reporting a bugprone-use-after-move false positive on x = {} immediately after std::move(x), which is the documented way to restore a moved-from object. The pinned version is what found the gmtime_r defect above.

Version Parses host libstdc++ use-after-move false positive Found gmtime_r defect
18 ✗ bails early yes no
20 (pinned) no
22 no no

The gate passes --warnings-as-errors, because plain clang-tidy exits 0 even when it reports diagnostics.

Verification

152/152 C++ tests (three new) including asan and ubsan, 45/45 Dart, UBSan clean on both hostile inputs after the fix, clang-tidy clean at the pinned version, clang-format applied last, dart analyze --fatal-infos clean, dart pub publish --dry-run 0 warnings.

No API changes.

Full changelog: https://github.com/flatpak-minimal/appstream_dart/blob/v0.4.2/CHANGELOG.md