<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vladimir Garenitsa</title>
    <description>The latest articles on DEV Community by Vladimir Garenitsa (@malwaredante).</description>
    <link>https://dev.to/malwaredante</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4177963%2Fb1e7198d-f419-4507-b626-dbd9f7603480.png</url>
      <title>DEV Community: Vladimir Garenitsa</title>
      <link>https://dev.to/malwaredante</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/malwaredante"/>
    <language>en</language>
    <item>
      <title>Android's external/ libraries: hunting n-days in code that upstream already fixed</title>
      <dc:creator>Vladimir Garenitsa</dc:creator>
      <pubDate>Mon, 12 Oct 2026 00:17:52 +0000</pubDate>
      <link>https://dev.to/malwaredante/androids-external-libraries-hunting-n-days-in-code-that-upstream-already-fixed-159l</link>
      <guid>https://dev.to/malwaredante/androids-external-libraries-hunting-n-days-in-code-that-upstream-already-fixed-159l</guid>
      <description>&lt;p&gt;&lt;strong&gt;"Android's &lt;code&gt;external/&lt;/code&gt; libraries: hunting n-days in code that upstream already fixed"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Alternative: "I built a fuzzing platform on a 2-core VPS. Here's what actually works for solo vuln research")&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Draft text
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;By Vladimir Garenitsa / MalwareDante&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everyone hunting memory-corruption bugs in open-source media libraries&lt;br&gt;
competes with Google's OSS-Fuzz — a cluster running the same fuzzers on the&lt;br&gt;
same code, 24/7. On a 2-core VPS you lose that race by definition.&lt;/p&gt;

&lt;p&gt;So I stopped racing and changed the question: &lt;strong&gt;not "how do I fuzz more", but&lt;br&gt;
"what does nobody fuzz?"&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Three surfaces that aren't crowded
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Vendor forks, not upstream.&lt;/strong&gt;&lt;br&gt;
AOSP ships vendored copies of parsing libraries under &lt;code&gt;external/&lt;/code&gt; — and they&lt;br&gt;
lag upstream, sometimes catastrophically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;external/libexif&lt;/code&gt; is &lt;strong&gt;0.6.21 — last upgraded June 2015&lt;/strong&gt;. Eleven years of
upstream fixes never merged (though Google cherry-picks CVE fixes — the
hot paths are patched; the rest is a gray zone).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;external/flac&lt;/code&gt; is &lt;strong&gt;1.4.3 vs upstream 1.5.0&lt;/strong&gt;, which includes real
parser-hardening: residual-in-32-bit-overflow checks, metadata
over-read/allocation guards. Those checks do not exist in shipped code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you fuzz the &lt;em&gt;shipped&lt;/em&gt; version instead of upstream, you hunt in&lt;br&gt;
pre-mapped territory — and a hit is an &lt;strong&gt;n-day on every Android device&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The write path.&lt;/strong&gt;&lt;br&gt;
Nearly every media-fuzzer feeds files into decoders. Almost nobody fuzzes&lt;br&gt;
&lt;strong&gt;encode→serialize→reparse&lt;/strong&gt; loops — yet that path touches different&lt;br&gt;
machinery (box writers, CRC builders, metadata serialization). I built a&lt;br&gt;
round-trip harness (decode HEIF → re-encode via x265 → write → reparse →&lt;br&gt;
decode). On a mature decoder, the write path is the least-exercised code in&lt;br&gt;
the tree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Sanitizer classes people skip.&lt;/strong&gt;&lt;br&gt;
Everyone runs ASan+UBSan. Fewer run &lt;strong&gt;MemorySanitizer&lt;/strong&gt; — it requires&lt;br&gt;
building the entire dependency tree under &lt;code&gt;-fsanitize=memory&lt;/code&gt;, which is&lt;br&gt;
tedious, so coverage stays thin. UMR-class bugs hide precisely there.&lt;/p&gt;

&lt;h3&gt;
  
  
  The platform
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;12 libFuzzer targets + AFL++ CmpLog + guided MSan, in &lt;code&gt;systemd-run&lt;/code&gt; scopes
with CPU quotas (a 2-core VPS shares it fine)&lt;/li&gt;
&lt;li&gt;Daily &lt;code&gt;git pull → incremental rebuild → relaunch&lt;/code&gt; via systemd timer —
"bleeding edge" commits get fuzzed hours after landing&lt;/li&gt;
&lt;li&gt;Automated triage: stack-signature dedup, append-only crash index, 1-minute
telemetry, watchdog restarts. I check in twice a day; the fleet runs itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Honest results (as of writing)
&lt;/h3&gt;

&lt;p&gt;778 triaged artifacts, 97 signatures — all UB-class, zero memory corruption&lt;br&gt;
&lt;em&gt;so far&lt;/em&gt;. One real unfixed bug reported upstream:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/strukturag/libde265/issues/546" rel="noopener noreferrer"&gt;libde265#546&lt;/a&gt;&lt;/strong&gt; —&lt;br&gt;
attacker-controlled invalid enum load in SEI &lt;code&gt;decoded_picture_hash&lt;/code&gt;, live in&lt;br&gt;
release 1.1.2 and git master.&lt;/p&gt;

&lt;p&gt;The honest pitch: solo fuzzing won't out-muscle OSS-Fuzz, but it can&lt;br&gt;
out-&lt;em&gt;position&lt;/em&gt; it. The edge isn't compute — it's surface selection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source, harnesses and methodology:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/malwaredante/fuzzing-infra" rel="noopener noreferrer"&gt;github.com/malwaredante/fuzzing-infra&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vladimir Garenitsa / MalwareDante — independent vulnerability research.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>android</category>
      <category>fuzzing</category>
      <category>cve</category>
    </item>
  </channel>
</rss>
