Low watch CVSS 6.5 chrome Uninitialized Memory 🔧 Commit mapped

Overview

Low
Severity
6.5
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUninitialized Use in Skia
DescriptionUninitialized Use in Skia
ComponentSkia
Bug ClassUninitialized Memory
Action tierwatch — information disclosure — security-relevant, below the RCE-class bar
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker520506316
Fix commitda379fdf722d (skia) +70/-2
CWECWE-457 (Use of uninitialized)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-06-05 (per vendor advisory)
Fix landed2026-06-17 (public git)
Disclosed2026-07-29
Patch gap42 days — fix public in source before the advisory

Background

Conic
A rational quadratic curve segment in Skia defined by two control points plus a scalar weight w, appended to a path through SkPathBuilder::conicTo.
`SkPathBuilder`
The mutable builder that accumulates path verbs, points, and conic weights before producing an immutable SkPath via detach.
Degenerate conic
A conic whose weight is not a normal positive value (e.g. zero, negative, or non-finite), which SkPath/SkGeometry cannot process as an ordinary curve and historically demoted to a line.
`SkGeometry`
Skia’s low-level curve math (evaluation, chopping, measurement) that assumes conic weights are strictly positive.

Root Cause Analysis

SkPathBuilder::conicTo in src/core/SkPathBuilder.cpp only special-cased a weight w of exactly one (demoted to a quad) and a non-finite w (demoted to two lines), but otherwise appended a kConic_Verb with whatever w the caller supplied, including zero or negative values. This violated the invariant, documented in SkGeometry.h, that conic weights are strictly positive; per the commit message the older SkPath code path had explicitly demoted such degenerate conics to a lineTo, and that guard had been lost in the builder. Downstream consumers such as SkGeometry and SkPathMeasure then operated on a conic whose weight was zero (which the regression test shows can also arise when a transform like makeTransform collapses a previously positive weight to 0), producing an assertion failure and, per the advisory’s UninitializedMemory classification, use of uninitialized memory.

The fix restores the demotion by adding if (w <= 0) { return this->lineTo(pt2); } at the top of conicTo, so any non-positive weight becomes a well-defined line to pt2 instead of an invalid conic. This works because it re-establishes the positive-weight precondition before any conic verb, point, or weight is ever stored.

Key insight
The single mistake was that SkPathBuilder::conicTo failed to enforce SkGeometry’s positive-weight invariant, admitting w <= 0 conics that downstream math treats as valid; the fix simply demotes every non-positive-weight conic to a lineTo(pt2), eliminating the degenerate curve at the source.

Attack Path

  1. Supply a path with a non-positive conic weight Through any surface that builds a path via SkPathBuilder::conicTo (e.g. graphics content that maps to Skia path construction), the attacker specifies a conic with w <= 0, or a weight that a later transform collapses to 0.
  2. Bypass the demotion guards Because the original conicTo only handled w == 1 and non-finite w, the zero/negative weight is stored verbatim as a kConic_Verb with its point and weight, retained through detach into an SkPath.
  3. Trigger degenerate-conic math Consuming the path (the regression test drives this via makeTransform followed by SkPathMeasure::getLength) invokes SkGeometry routines that assume a positive weight, hitting the assertion the test describes and the advisory’s uninitialized-memory condition.
  4. Escalate from uninitialized use Any read/write primitive, out-of-bounds access, or code execution beyond the uninitialized-memory use is not demonstrated by the diff (inferred).

Impact Assessment

An attacker who controls path geometry reaching Skia can create a zero/negative-weight conic that causes use of uninitialized memory (the advisory classes this as UninitializedMemory, “Uninitialized Use in Skia”), reachable during path evaluation such as transform and measurement. The preconditions are limited to being able to build or supply a path with a non-positive (or transform-nulled) conic weight. The vendor advisory rates this low severity and does not report in-the-wild exploitation; NVD scores it CVSS 6.5. The advisory provided no exploited-in-the-wild status or severity rating beyond the stated impact.

Changed Functions

FunctionChangeNotes
if
src/core/SkPathBuilder.cpp
modified
DEF_TEST
tests/PathBuilderTest.cpp
modified

Files Changed

  • include/core/SkPathBuilder.h
  • src/core/SkPathBuilder.cpp
  • tests/PathBuilderTest.cpp

Audit Directions

  • Missing invariant checks at builder entry points
    Audit other SkPathBuilder and SkPath methods (and any curve constructors) to confirm they reject or normalize out-of-domain inputs before storing verbs, points, or weights.
  • Weight/parameter assumptions in low-level math
    Review SkGeometry and SkPathMeasure routines that assume strictly positive conic weights (per SkGeometry.h) and verify every caller guarantees that precondition.
  • Transform-induced degeneracy
    Look for places where a previously valid parameter can become degenerate after operations like makeTransform, and ensure such collapsed values are re-validated rather than fed directly into curve math.
From da379fdf722dc5df60caefed012952117a5ce4b4 Mon Sep 17 00:00:00 2001
From: Kaylee Lubick <kjlubick@google.com>
Date: Tue, 16 Jun 2026 16:59:17 -0400
Subject: [PATCH] Handle w<=0 conics

SkPath had special logic for degenerate conics [1] and SkGeometry
has an assumption of positive weights [2][3] (possibly other places
too), so this restores that logic to turn it into a lineTo.

[1] https://github.com/google/skia/blob/19936eb1b23fef5187b07fb2e0e67dcf605c0672/src/core/SkPath.cpp#L754-L756
[2] https://github.com/google/skia/blob/d7196b0b493925df3be1e259f41a3c6678732b45/src/core/SkGeometry.h#L350
[3] https://review.skia.org/667436
[4] https://review.skia.org/1225597

Bug: 520506316
Change-Id: I6946e755c5cacade8a487bc882ba0ce5e34531a1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1267718
Auto-Submit: Kaylee Lubick <kjlubick@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Florin Malita <fmalita@google.com>
---

diff --git a/include/core/SkPathBuilder.h b/include/core/SkPathBuilder.h
index d4b1907..ad6882d 100644
--- a/include/core/SkPathBuilder.h
+++ b/include/core/SkPathBuilder.h
@@ -252,12 +252,14 @@
 
         Appends kMove_Verb to verb array and (0, 0) to SkPoint array, if needed.
 
-        If w is finite and not one, appends kConic_Verb to verb array;
+        If w is finite, positive, and not one, appends kConic_Verb to verb array;
         and pt1, pt2 to SkPoint array; and w to conic weights.
 
         If w is one, appends kQuad_Verb to verb array, and
         pt1, pt2 to SkPoint array.
 
+        If w is zero, this is the same as lineTo(pt2)
+
         If w is not finite, appends kLine_Verb twice to verb array, and
         pt1, pt2 to SkPoint array.
 
diff --git a/src/core/SkPathBuilder.cpp b/src/core/SkPathBuilder.cpp
index 76d418a..833763d 100644
--- a/src/core/SkPathBuilder.cpp
+++ b/src/core/SkPathBuilder.cpp
@@ -202,6 +202,9 @@
 SkPathBuilder& SkPathBuilder::conicTo(SkPoint pt1, SkPoint pt2, SkScalar w) {
     this->ensureMove();
 
+    if (w <= 0) {
+        return this->lineTo(pt2);
+    }
     SkPoint* p = fPts.push_back_n(2);
     p[0] = pt1;
     p[1] = pt2;
diff --git a/tests/PathBuilderTest.cpp b/tests/PathBuilderTest.cpp
index ba22ad3..b152e8d 100644
--- a/tests/PathBuilderTest.cpp
+++ b/tests/PathBuilderTest.cpp
@@ -7,6 +7,7 @@
 
 #include "include/core/SkPath.h"
 #include "include/core/SkPathBuilder.h"
+#include "include/core/SkPathMeasure.h"
 #include "include/core/SkPathTypes.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkRRect.h"
@@ -1098,11 +1099,73 @@
     {
         // If w is not finite, appends kLine_Verb twice to verb array, and
         // pt1, pt2 to SkPoint array.
-        SkPath p = SkPathBuilder().conicTo({10, 5}, {10, 10}, SK_ScalarInfinity).detach();
+        SkPath p = SkPathBuilder().conicTo({10, 5}, {10, 10}, SK_FloatInfinity).detach();
         REPORTER_ASSERT(reporter, !p.isEmpty());
         REPORTER_ASSERT(reporter, p.verbs().size() == 3u); // moveTo, lineTo, lineTo
         REPORTER_ASSERT(reporter, p.points().size() == 3u);
         REPORTER_ASSERT(reporter, p.conicWeights().empty());
         REPORTER_ASSERT(reporter, p.getSegmentMasks() == SkPath::kLine_SegmentMask);
     }
+
+    {
+        // If w is 0, appends kLine_Verb once to verb array, and
+        // pt2 to SkPoint array.
+        SkPath p = SkPathBuilder().conicTo({10, 5}, {10, 10}, 0).detach();
+        REPORTER_ASSERT(reporter, !p.isEmpty());
+        REPORTER_ASSERT(reporter, p.verbs().size() == 2u); // moveTo, lineTo
+        REPORTER_ASSERT(reporter, p.points().size() == 2u);
+        REPORTER_ASSERT(reporter, p.conicWeights().empty());
+        REPORTER_ASSERT(reporter, p.getSegmentMasks() == SkPath::kLine_SegmentMask);
+    }
+}
+
+DEF_TEST(SkPathBuilder_b520944501, reporter) {
+    SkPath path = SkPathBuilder(SkPathFillType::kInverseEvenOdd)
+                          .moveTo(0, 0)
+                          .cubicTo(8.51330895e-18f,
+                                   4.80215861e+30f,
+                                   4.80215347e+30f,
+                                   4.73888368e-38f,
+                                   2.36942783e-38f,
+                                   7.54830852e-30f)
+                          .moveTo(4.80215831e+30f, 1.03969141e-21f)
+                          .conicTo(4.80215831e+30f,
+                                   4.73888368e-38f,
+                                   2.40107915e+30f,
+                                   4.73888368e-38f,
+                                   0.707106769f)
+                          .conicTo(2.0779294e-21f,
+                                   4.73888368e-38f,
+                                   2.0779294e-21f,
+                                   1.03969141e-21f,
+                                   0.707106769f)
+                          .conicTo(2.0779294e-21f,
+                                   2.07938282e-21f,
+                                   2.40107915e+30f,
+                                   2.07938282e-21f,
+                                   0.707106769f)
+                          .conicTo(4.80215831e+30f,
+                                   2.07938282e-21f,
+                                   4.80215831e+30f,
+                                   1.03969141e-21f,
+                                   0.707106769f)
+                          .close()
+                          .detach();
+
+    SkMatrix m;
+    m.setAll(0.0f,
+             0.0f,
+             0.0f,
+             0.0f,
+             0.0f,
+             10159839284371128320.0f,
+             36261335138304000.0f,
+             0.0f,
+             -0.0f);
+
+    // This previously caused an issue where one of the conic weights turned to
+    // 0, causing an assert later. We should be avoiding that.
+    SkPath transformed = path.makeTransform(m);
+    SkPathMeasure meas(transformed, false);
+    (void)meas.getLength();
 }
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.