Medium watch CVSS 4.3 chrome OOB 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactOut of bounds read in WebCodecs
DescriptionOut of bounds read in WebCodecs
ComponentWebCodecs
Bug ClassOOB
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.
Tracker488585490
Fix commitd20e271c144e (webm/libvpx) +26/-27
CWECWE-125 (Out-of-bounds read)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
CISA KEVNot listed
Creditedheapracer (@heapracer)
Reported2026-03-01 (per vendor advisory)
Fix landed2026-03-30 (public git)
Disclosed2026-05-05
Patch gap36 days — fix public in source before the advisory

Background

libvpx VP9 encoder (`vp9/vp9_cx_iface.c`)
the VP9 encoder interface used by Chrome’s WebCodecs VideoEncoder for VP9; it ingests caller-supplied vpx_image_t frames.
High bit depth (`CONFIG_VP9_HIGHBITDEPTH`, `VPX_IMG_FMT_HIGHBITDEPTH`)
modes where samples are stored as 16-bit unsigned short values representing 10/12-bit (or more) pixels, with a valid range of [0, 1<<bit_depth).
`validate_img`
the encoder’s image-validation routine (named in the commit subject) that checks a submitted image before encoding and returns VPX_CODEC_INVALID_PARAM on bad input, VPX_CODEC_OK otherwise.
`validate_input_hbd`
an extra_cfg flag enabling per-sample range validation of high-bit-depth input.

Root Cause Analysis

The per-sample high-bit-depth range check (loop over planes verifying src[j] < (1 << bit_depth) and returning VPX_CODEC_INVALID_PARAM otherwise) previously lived in the encode entry path (the second hunk’s function, whose enclosing name is not shown in the @@ -1459 header) and was gated by three conditions: validate_input_hbd, VPX_IMG_FMT_HIGHBITDEPTH, and additionally ctx->oxcf.input_bit_depth > 8. That extra > 8 gate meant a frame flagged as high-bit-depth but configured with input_bit_depth == 8 skipped the range validation entirely, so out-of-range 16-bit samples could pass through; downstream high-bit-depth processing then treats those values as valid, leading to the out-of-bounds read the advisory reports (the specific indexed sink is inferred, not shown in the diff).

The fix moves the identical validation into validate_img (so it runs as part of normal image validation, before encoding) and drops the input_bit_depth > 8 condition, so any high-bit-depth-formatted image with validate_input_hbd set is range-checked. The check runs before the return VPX_CODEC_OK, rejecting out-of-range samples up front.

Key insight
The sample-range validation for high-bit-depth input was both misplaced (in the encode path rather than image validation) and over-gated by input_bit_depth > 8, letting out-of-range samples slip through for 8-bit-configured high-bit-depth images; moving it into validate_img and removing that gate makes every high-bit-depth frame get range-checked before use.

Attack Path

  1. Submit a high-bit-depth frame Via WebCodecs, content feeds the VP9 encoder a vpx_image_t flagged VPX_IMG_FMT_HIGHBITDEPTH while the encoder is configured with input_bit_depth == 8.
  2. Skip the range check Pre-patch, the ctx->oxcf.input_bit_depth > 8 gate makes the per-sample validation loop not run, so samples >= (1 << bit_depth) are never rejected.
  3. Pass out-of-range samples downstream The unchecked 16-bit sample values flow into high-bit-depth encoding logic that assumes in-range pixels.
  4. Out-of-bounds read The out-of-range sample values drive an out-of-bounds read during encoding (the exact indexed location is inferred and not demonstrated by the diff).

Impact Assessment

A web page using WebCodecs VP9 encoding can submit crafted high-bit-depth frames to reach the vulnerable path in the renderer/encoder, with no special privileges beyond calling the API. The advisory rates this medium severity and classifies it as an out-of-bounds read in WebCodecs; it does not report in-the-wild exploitation. Any information disclosure or escalation from the OOB read is (inferred) and not demonstrated by the patch.

Changed Functions

FunctionChangeNotes
for
vp9/vp9_cx_iface.c
modified
if
vp9/vp9_cx_iface.c
modified

Files Changed

  • vp9/vp9_cx_iface.c

Audit Directions

  • Over-gated input validation
    Audit range/format checks guarded by extra conditions (like input_bit_depth > 8) that can exclude attacker-reachable formats; confirm the gate matches the actual danger set.
  • Validation placed off the validation path
    Review checks performed in encode/process entry points rather than the dedicated validate_* routine, which can be bypassed by paths that skip them.
  • High-bit-depth sample bounds
    Check other codec interfaces (vp8, AV1, etc.) that interpret 16-bit samples for VPX_IMG_FMT_HIGHBITDEPTH without verifying each sample is within [0, 1<<bit_depth) before indexing.
From d20e271c144ee80e5c6025b26bc01a8b8c59a187 Mon Sep 17 00:00:00 2001
From: Marco Paniconi <[email protected]>
Date: Mon, 30 Mar 2026 14:17:30 -0700
Subject: [PATCH] vp9; move source input check to validate_img

And remove the check:
ctx->oxcf.input_bit_depth > 8

Bug: 488585490
Change-Id: Ibf73572d9db20e8a731fffe363675a7f8173d4f7
---

diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 6397e2d..c1fbccc 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -430,6 +430,32 @@
   if (img->stride[VPX_PLANE_U] != img->stride[VPX_PLANE_V])
     ERROR("Image U/V strides must match");
 
+#if CONFIG_VP9_HIGHBITDEPTH
+  if (ctx->extra_cfg.validate_input_hbd &&
+      (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH)) {
+    const unsigned int h = img->d_h;
+    const unsigned int w = img->d_w;
+    const unsigned int bit_depth = ctx->oxcf.input_bit_depth;
+    const int max_val = 1 << bit_depth;
+    for (int plane = 0; plane < 3; ++plane) {
+      const unsigned short *src = (const unsigned short *)img->planes[plane];
+      const unsigned int stride = img->stride[plane] / 2;
+      const unsigned int ph =
+          (plane == 0) ? h : (h + img->y_chroma_shift) >> img->y_chroma_shift;
+      const unsigned int pw =
+          (plane == 0) ? w : (w + img->x_chroma_shift) >> img->x_chroma_shift;
+      for (unsigned int i = 0; i < ph; ++i) {
+        for (unsigned int j = 0; j < pw; ++j) {
+          if (src[j] >= max_val) {
+            return VPX_CODEC_INVALID_PARAM;
+          }
+        }
+        src += stride;
+      }
+    }
+  }
+#endif  // CONFIG_VP9_HIGHBITDEPTH
+
   return VPX_CODEC_OK;
 }
 
@@ -1459,33 +1485,6 @@
   if (img != NULL) {
     YV12_BUFFER_CONFIG sd;
 
-#if CONFIG_VP9_HIGHBITDEPTH
-    if (ctx->extra_cfg.validate_input_hbd &&
-        (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) &&
-        ctx->oxcf.input_bit_depth > 8) {
-      const unsigned int h = img->d_h;
-      const unsigned int w = img->d_w;
-      const unsigned int bit_depth = ctx->oxcf.input_bit_depth;
-      const int max_val = 1 << bit_depth;
-      for (int plane = 0; plane < 3; ++plane) {
-        const unsigned short *src = (const unsigned short *)img->planes[plane];
-        const unsigned int stride = img->stride[plane] / 2;
-        const unsigned int ph =
-            (plane == 0) ? h : (h + img->y_chroma_shift) >> img->y_chroma_shift;
-        const unsigned int pw =
-            (plane == 0) ? w : (w + img->x_chroma_shift) >> img->x_chroma_shift;
-        for (unsigned int i = 0; i < ph; ++i) {
-          for (unsigned int j = 0; j < pw; ++j) {
-            if (src[j] >= max_val) {
-              return VPX_CODEC_INVALID_PARAM;
-            }
-          }
-          src += stride;
-        }
-      }
-    }
-#endif  // CONFIG_VP9_HIGHBITDEPTH
-
     if (!ctx->pts_offset_initialized) {
       ctx->pts_offset = pts;
       ctx->pts_offset_initialized = 1;
Loading diff…

Original Bug Report

reported by [email protected]

Buffer overflow in vp9_get_token_cost via crafted VideoEncoder frame sequence

VULNERABILITY DETAILS

A crafted WebCodecs VideoEncoder VP9 sequence triggers an out-of-bounds read in libvpx at vp9_get_token_cost. The issue is attacker-influenced through coefficient values that drive v, which is converted into extrabits = abs(v) - CAT6_MIN_VAL, then indexed as cat6_high_table[extrabits >> 8] without a sufficient bounds check for all reachable values. This yields an attacker-influenced 2-byte out-of-bounds read (table element type is uint16_t) in the renderer process during VP9 encode cost computation.

Crash Log:

=================================================================
==3855047==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7fe749294a92 at pc 0x7fe74bd808b0 bp 0x7be206f94d80 sp 0x7be206f94d78
READ of size 2 at 0x7fe749294a92 thread T4 (ThreadPoolForeg)
    #0 0x7fe74bd808af in vp9_get_token_cost third_party/libvpx/source/libvpx/vp9/encoder/vp9_tokenize.h:120:12
    #1 0x7fe74bd7fcb8 in cost_coeffs third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:426:14
    #2 0x7fe74bd7edf9 in rate_block third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:695:10
    #3 0x7fe74bd7a98a in block_rd_txfm third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:826:10
    #4 0x7fe74bb8220c in vp9_foreach_transformed_block_in_plane third_party/libvpx/source/libvpx/vp9/common/vp9_blockd.c:70:7
    #5 0x7fe74bd78850 in txfm_rd_in_plane third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:876:3
    #6 0x7fe74bd74e62 in choose_largest_tx_size third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:903:3
    #7 0x7fe74bd749ce in super_block_yrd third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:1036:5
    #8 0x7fe74bd72505 in rd_pick_intra_sby_mode third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:1393:5
    #9 0x7fe74bd71611 in vp9_rd_pick_intra_mode_sb third_party/libvpx/source/libvpx/vp9/encoder/vp9_rdopt.c:3240:9
    #10 0x7fe74bc47be4 in hybrid_intra_mode_search third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:4351:5
    #11 0x7fe74bc46fa3 in nonrd_pick_sb_modes third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:4422:5
    #12 0x7fe74bc35c05 in nonrd_use_partition third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5020:7
    #13 0x7fe74bc3758c in nonrd_use_partition third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5083:9
    #14 0x7fe74bc376b5 in nonrd_use_partition third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5085:9
    #15 0x7fe74bc3758c in nonrd_use_partition third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5083:9
    #16 0x7fe74bc25ef1 in encode_nonrd_sb_row third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5310:9
    #17 0x7fe74bc23df0 in vp9_encode_sb_row third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5472:3
    #18 0x7fe74bcad84c in enc_row_mt_worker_hook third_party/libvpx/source/libvpx/vp9/encoder/vp9_ethread.c:617:7
    #19 0x7fe74a001158 in media::CodecWorkerImpl<VPxWorkerInterface, VPxWorkerImpl, VPxWorker, VPxWorkerStatus, (VPxWorkerStatus)0, (VPxWorkerStatus)1, (VPxWorkerStatus)2>::Execute(VPxWorker*) media/base/codec_worker_impl.h:69:29
    #20 0x7fe74bcab4ad in launch_enc_workers third_party/libvpx/source/libvpx/vp9/encoder/vp9_ethread.c:163:7
    #21 0x7fe74bcad26f in vp9_encode_tiles_row_mt third_party/libvpx/source/libvpx/vp9/encoder/vp9_ethread.c:680:3
    #22 0x7fe74bc2c5ed in encode_frame_internal third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5741:7
    #23 0x7fe74bc296db in vp9_encode_frame third_party/libvpx/source/libvpx/vp9/encoder/vp9_encodeframe.c:5953:5
    #24 0x7fe74bca2b3e in encode_without_recode_loop third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c:4277:3
    #25 0x7fe74bc9851c in encode_frame_to_data_rate third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c:5390:10
    #26 0x7fe74bc8b465 in Pass0Encode third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c:5669:3
    #27 0x7fe74bc89643 in vp9_get_compressed_data third_party/libvpx/source/libvpx/vp9/encoder/vp9_encoder.c:6434:5
    #28 0x7fe74bdc9fa7 in encoder_encode third_party/libvpx/source/libvpx/vp9/vp9_cx_iface.c:1556:20
    #29 0x7fe74bdf8e7f in vpx_codec_encode third_party/libvpx/source/libvpx/vpx/src/vpx_encoder.c:218:13
    #30 0x7fe74aabdc51 in media::VpxVideoEncoder::Encode(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>) media/video/vpx_video_encoder.cc:742:20
    #31 0x7fe74aa1b03b in void base::internal::DecayedFunctorTraits<void (media::VideoEncoder::*)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), media::VideoEncoder*, scoped_refptr<media::VideoFrame>&&, media::VideoEncoder::EncodeOptions&&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>&&>::Invoke<void (media::VideoEncoder::*)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), media::VideoEncoder*, scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>(void (media::VideoEncoder::*)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), media::VideoEncoder*&&, scoped_refptr<media::VideoFrame>&&, media::VideoEncoder::EncodeOptions&&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>&&) base/functional/bind_internal.h:740:12
    #32 0x7fe74aa1ad74 in void base::internal::InvokeHelper<false, base::internal::FunctorTraits<void (media::VideoEncoder::*&&)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), media::VideoEncoder*, scoped_refptr<media::VideoFrame>&&, media::VideoEncoder::EncodeOptions&&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>&&>, void, 0ul, 1ul, 2ul, 3ul>::MakeItSo<void (media::VideoEncoder::*)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), std::__Cr::tuple<base::internal::UnretainedWrapper<media::VideoEncoder, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>, scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>>(void (media::VideoEncoder::*&&)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), std::__Cr::tuple<base::internal::UnretainedWrapper<media::VideoEncoder, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>, scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>&&) base/functional/bind_internal.h:932:12
    #33 0x7fe74aa1aa47 in void base::internal::Invoker<base::internal::FunctorTraits<void (media::VideoEncoder::*&&)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), media::VideoEncoder*, scoped_refptr<media::VideoFrame>&&, media::VideoEncoder::EncodeOptions&&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>&&>, base::internal::BindState<true, true, false, void (media::VideoEncoder::*)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), base::internal::UnretainedWrapper<media::VideoEncoder, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>, scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>, void ()>::RunImpl<void (media::VideoEncoder::*)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), std::__Cr::tuple<base::internal::UnretainedWrapper<media::VideoEncoder, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>, scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>, 0ul, 1ul, 2ul, 3ul>(void (media::VideoEncoder::*&&)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), std::__Cr::tuple<base::internal::UnretainedWrapper<media::VideoEncoder, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>, scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>&&, std::__Cr::integer_sequence<unsigned long, 0ul, 1ul, 2ul, 3ul>) base/functional/bind_internal.h:1069:14
    #34 0x7fe74aa1a878 in base::internal::Invoker<base::internal::FunctorTraits<void (media::VideoEncoder::*&&)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), media::VideoEncoder*, scoped_refptr<media::VideoFrame>&&, media::VideoEncoder::EncodeOptions&&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>&&>, base::internal::BindState<true, true, false, void (media::VideoEncoder::*)(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>), base::internal::UnretainedWrapper<media::VideoEncoder, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0>, scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>, void ()>::RunOnce(base::internal::BindStateBase*) base/functional/bind_internal.h:982:12
    #35 0x7fe77f1ce112 in base::OnceCallback<void ()>::Run() && base/functional/callback.h:155:12
    #36 0x7fe77f6fa12e in base::TaskAnnotator::RunTaskImpl(base::PendingTask&) base/task/common/task_annotator.cc:229:34
    #37 0x7fe77f8e77d7 in void base::TaskAnnotator::RunTask<base::internal::TaskTracker::RunTaskImpl(base::internal::Task&, base::TaskTraits const&, base::internal::TaskSource*, base::internal::SequenceToken const&)::$_0>(perfetto::StaticString, base::PendingTask&, base::internal::TaskTracker::RunTaskImpl(base::internal::Task&, base::TaskTraits const&, base::internal::TaskSource*, base::internal::SequenceToken const&)::$_0&&) base/task/common/task_annotator.h:112:5
    #38 0x7fe77f8e7274 in base::internal::TaskTracker::RunTaskImpl(base::internal::Task&, base::TaskTraits const&, base::internal::TaskSource*, base::internal::SequenceToken const&) base/task/thread_pool/task_tracker.cc:691:19
    #39 0x7fe77f8e7428 in base::internal::TaskTracker::RunSkipOnShutdown(base::internal::Task&, base::TaskTraits const&, base::internal::TaskSource*, base::internal::SequenceToken const&) base/task/thread_pool/task_tracker.cc:676:3
    #40 0x7fe77f8e593d in base::internal::TaskTracker::RunTaskWithShutdownBehavior(base::internal::Task&, base::TaskTraits const&, base::internal::TaskSource*, base::internal::SequenceToken const&) base/task/thread_pool/task_tracker.cc:706:7
    #41 0x7fe77f8e4a49 in base::internal::TaskTracker::RunTask(base::internal::Task, base::internal::TaskSource*, base::TaskTraits const&, base::ThreadType) base/task/thread_pool/task_tracker.cc:506:5
    #42 0x7fe77f8e3593 in base::internal::TaskTracker::RunAndPopNextTask(base::internal::RegisteredTaskSource) base/task/thread_pool/task_tracker.cc:394:5
    #43 0x7fe77f936243 in base::internal::WorkerThread::RunWorker() base/task/thread_pool/worker_thread.cc:473:36
    #44 0x7fe77f9355ab in base::internal::WorkerThread::RunPooledWorker() base/task/thread_pool/worker_thread.cc:359:3
    #45 0x7fe77f934e25 in base::internal::WorkerThread::ThreadMain() base/task/thread_pool/worker_thread.cc:339:7
    #46 0x7fe77faa706c in base::(anonymous namespace)::ThreadFunc(void*) base/threading/platform_thread_posix.cc:102:13
    #47 0x562fe99bd896 in asan_thread_start(void*) asan_interceptors.cpp

0x7fe749294a92 is located 18 bytes after global variable 'vp9_cat6_high10_high_cost' defined in '../../third_party/libvpx/source/libvpx/vp9/encoder/vp9_tokenize.c' (0x7fe749294880) of size 512
SUMMARY: AddressSanitizer: global-buffer-overflow third_party/libvpx/source/libvpx/vp9/encoder/vp9_tokenize.h:120:12 in vp9_get_token_cost
Shadow bytes around the buggy address:
  0x7fe749294800: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9
  0x7fe749294880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fe749294900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fe749294980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fe749294a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7fe749294a80: f9 f9[f9]f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x7fe749294b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fe749294b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fe749294c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fe749294c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fe749294d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
Thread T4 (ThreadPoolForeg) created by T0 (chrome) here:
    #0 0x562fe99a36c1 in pthread_create (/mnt/lvm_data/chromium/src/out/asan_dbg_symbols/chrome+0xf3406c1) (BuildId: 3afd3fb7d064a1b6)
    #1 0x7fe77faa5b69 in base::(anonymous namespace)::CreateThread(unsigned long, bool, base::PlatformThreadBase::Delegate*, base::PlatformThreadHandle*, base::ThreadType, base::MessagePumpType) base/threading/platform_thread_posix.cc:153:13
    #2 0x7fe77faa56c8 in base::PlatformThreadBase::CreateWithType(unsigned long, base::PlatformThreadBase::Delegate*, base::PlatformThreadHandle*, base::ThreadType, base::MessagePumpType) base/threading/platform_thread_posix.cc:322:10
    #3 0x7fe77f9327b8 in base::internal::WorkerThread::Start(scoped_refptr<base::SingleThreadTaskRunner>, base::WorkerThreadObserver*) base/task/thread_pool/worker_thread.cc:185:3
    #4 0x7fe77f8f34b4 in base::internal::ThreadGroup::BaseScopedCommandsExecutor::Flush() base/task/thread_pool/thread_group.cc:65:13
    #5 0x7fe77f8f3289 in base::internal::ThreadGroup::BaseScopedCommandsExecutor::~BaseScopedCommandsExecutor() base/task/thread_pool/thread_group.cc:56:3
    #6 0x7fe77f9126bf in base::internal::ThreadGroupImpl::ScopedCommandsExecutor::~ScopedCommandsExecutor() base/task/thread_pool/thread_group_impl.cc:71:3
    #7 0x7fe77f90549e in base::internal::ThreadGroupImpl::Start(unsigned long, unsigned long, base::TimeDelta, scoped_refptr<base::SingleThreadTaskRunner>, base::WorkerThreadObserver*, base::internal::ThreadGroup::WorkerEnvironment, bool, std::__Cr::optional<base::TimeDelta>) base/task/thread_pool/thread_group_impl.cc:289:3
    #8 0x7fe77f91bb7e in base::internal::ThreadPoolImpl::Start(base::ThreadPoolInstance::InitParams const&, base::WorkerThreadObserver*) base/task/thread_pool/thread_pool_impl.cc:197:35
    #9 0x7fe75a88459e in content::ChildProcess::ChildProcess(base::ThreadType, std::__Cr::unique_ptr<base::ThreadPoolInstance::InitParams, std::__Cr::default_delete<base::ThreadPoolInstance::InitParams>>, bool) content/child/child_process.cc:112:20
    #10 0x7fe7675ff616 in content::RenderProcess::RenderProcess(std::__Cr::unique_ptr<base::ThreadPoolInstance::InitParams, std::__Cr::default_delete<base::ThreadPoolInstance::InitParams>>) content/renderer/render_process.cc:18:7
    #11 0x7fe7675ff8cf in content::RenderProcessImpl::RenderProcessImpl() content/renderer/render_process_impl.cc:98:7
    #12 0x7fe767600460 in content::RenderProcessImpl::Create() content/renderer/render_process_impl.cc:223:31
    #13 0x7fe76765b8b2 in content::RendererMain(content::MainFunctionParams) content/renderer/renderer_main.cc:285:53
    #14 0x7fe76813c92a in content::RunZygote(content::ContentMainDelegate*) content/app/content_main_runner_impl.cc:664:14
    #15 0x7fe76813e163 in content::RunOtherNamedProcessTypeMain(std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>> const&, content::MainFunctionParams, content::ContentMainDelegate*) content/app/content_main_runner_impl.cc:771:12
    #16 0x7fe768141956 in content::ContentMainRunnerImpl::Run() content/app/content_main_runner_impl.cc:1152:10
    #17 0x7fe7681377af in content::RunContentProcess(content::ContentMainParams, content::ContentMainRunner*) content/app/content_main.cc:358:36
    #18 0x7fe768138625 in content::ContentMain(content::ContentMainParams) content/app/content_main.cc:371:10
    #19 0x562fe9a04700 in ChromeMain chrome/app/chrome_main.cc:191:12
    #20 0x562fe9a03f61 in main chrome/app/chrome_exe_main_aura.cc:17:10
    #21 0x7fe63e564d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16


==3855047==ADDITIONAL INFO

==3855047==Note: Please include this section with the ASan report.
Task trace:
    #0 0x7fe74aa166bc in media::OffloadingVideoEncoder::Encode(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>) media/video/offloading_video_encoder.cc:64:7
    #1 0x7fe74aa187fd in base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)> media::OffloadingVideoEncoder::WrapCallback<base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>>(base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>) media/video/offloading_video_encoder.cc:97:10
    #2 0x7fe74aa166bc in media::OffloadingVideoEncoder::Encode(scoped_refptr<media::VideoFrame>, media::VideoEncoder::EncodeOptions const&, base::OnceCallback<void (media::TypedStatus<media::EncoderStatusTraits>)>) media/video/offloading_video_encoder.cc:64:7


Command line: `/proc/self/exe --type=renderer --crashpad-handler-pid=3837542 --enable-crash-reporter=,custom --noerrdialogs --user-data-dir=/tmp/vp9_yes_crash_check_1772327959/profile --change-stack-guard-on-fork=enable --no-sandbox --disable-dev-shm-usage --autoplay-policy=no-user-gesture-required --ozone-platform=headless --disable-gpu-compositing --lang=en-US --num-raster-threads=4 --enable-main-frame-before-activation --renderer-client-id=5 --time-ticks-at-unix-epoch=-1755397479121000 --launch-time-ticks=16930486893472 --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14386064033147920290,12349290705452148965,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,11198883022770146187,4803122057752559843,4 --trace-process-track-uuid=1205913054661273622 --enable-logging=stderr`


==3855047==END OF ADDITIONAL INFO

VERSION Chrome Version: 146.0.7680.31 + stable (latest released, Chrome for Testing), 147.0.7703.0 + dev (latest preview, Chrome for Testing)

Operating System: Ubuntu 22.04.3 LTS (x86_64), Linux kernel 5.15.0-151-generic

REPRODUCTION CASE

Attached file:

  • repro_vp9_get_token_cost_min193.html

Repro steps (ASAN build):

  1. Launch Chromium ASAN build.
  2. Open repro_vp9_get_token_cost_min193.html.
  3. Observe renderer crash with global OOB in vp9_get_token_cost.

Type of crash: tab (renderer process)

Reporter credit: heapracer (@heapracer)

View on issue tracker