Chrome · GPU
CVE-2026-8534
Integer Overflow in GPU
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
gpu/command_buffer/service/gl_utils.cc
Patch
From 701332cc0468ea4c6283a911e683a8ac7c46f1eb Mon Sep 17 00:00:00 2001
From: Yuki Shiino <yukishiino@chromium.org>
Date: Tue, 24 Mar 2026 14:28:14 -0700
Subject: [PATCH] Fix possible integer overflow in gl::gles2::GetCompressedTexSizeInBytes
When width or height is enough huge, it's possible to cause
integer overflow in gl::gles2::GetCompressedTexSizeInBytes.
Applies base::CheckAdd and base::CheckDiv.
Bug: 495314407
Change-Id: Iff5addc01dadde00e68d170556adaea99415d2c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7693951
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Auto-Submit: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1604392}
---
diff --git a/gpu/command_buffer/service/gl_utils.cc b/gpu/command_buffer/service/gl_utils.cc
index 71f362f..c2772ae7 100644
--- a/gpu/command_buffer/service/gl_utils.cc
+++ b/gpu/command_buffer/service/gl_utils.cc
@@ -505,8 +505,10 @@
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
case GL_ETC1_RGB8_OES:
- bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
- bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
+ bytes_required = base::CheckDiv(
+ base::CheckAdd(width, kS3TCBlockWidth - 1), kS3TCBlockWidth);
+ bytes_required *= base::CheckDiv(
+ base::CheckAdd(height, kS3TCBlockHeight - 1), kS3TCBlockHeight);
bytes_required *= kS3TCDXT1BlockSize;
break;
case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
@@ -546,8 +548,10 @@
const int kBlockWidth = kASTCBlockArray[index].blockWidth;
const int kBlockHeight = kASTCBlockArray[index].blockHeight;
- bytes_required = (width + kBlockWidth - 1) / kBlockWidth;
- bytes_required *= (height + kBlockHeight - 1) / kBlockHeight;
+ bytes_required =
+ base::CheckDiv(base::CheckAdd(width, kBlockWidth - 1), kBlockWidth);
+ bytes_required *= base::CheckDiv(base::CheckAdd(height, kBlockHeight - 1),
+ kBlockHeight);
bytes_required *= kASTCBlockSize;
break;
@@ -558,8 +562,10 @@
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
- bytes_required = (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
- bytes_required *= (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
+ bytes_required = base::CheckDiv(
+ base::CheckAdd(width, kS3TCBlockWidth - 1), kS3TCBlockWidth);
+ bytes_required *= base::CheckDiv(
+ base::CheckAdd(height, kS3TCBlockHeight - 1), kS3TCBlockHeight);
bytes_required *= kS3TCDXT3AndDXT5BlockSize;
break;
case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
@@ -587,9 +593,11 @@
case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
bytes_required =
- (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
+ base::CheckDiv(base::CheckAdd(width, kEACAndETC2BlockSize - 1),
+ kEACAndETC2BlockSize);
bytes_required *=
- (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
+ base::CheckDiv(base::CheckAdd(height, kEACAndETC2BlockSize - 1),
+ kEACAndETC2BlockSize);
bytes_required *= 8;
bytes_required *= depth;
break;
@@ -598,9 +606,11 @@
case GL_COMPRESSED_RGBA8_ETC2_EAC:
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
bytes_required =
- (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
+ base::CheckDiv(base::CheckAdd(width, kEACAndETC2BlockSize - 1),
+ kEACAndETC2BlockSize);
bytes_required *=
- (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
+ base::CheckDiv(base::CheckAdd(height, kEACAndETC2BlockSize - 1),
+ kEACAndETC2BlockSize);
bytes_required *= 16;
bytes_required *= depth;
break;
@@ -608,22 +618,28 @@
case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
- bytes_required = (width + kBPTCBlockWidth - 1) / kBPTCBlockWidth;
- bytes_required *= (height + kBPTCBlockHeight - 1) / kBPTCBlockHeight;
+ bytes_required = base::CheckDiv(
+ base::CheckAdd(width, kBPTCBlockWidth - 1), kBPTCBlockWidth);
+ bytes_required *= base::CheckDiv(
+ base::CheckAdd(height, kBPTCBlockHeight - 1), kBPTCBlockHeight);
bytes_required *= 16;
bytes_required *= depth;
break;
case GL_COMPRESSED_RED_RGTC1_EXT:
case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
- bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
- bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
+ bytes_required = base::CheckDiv(
+ base::CheckAdd(width, kRGTCBlockWidth - 1), kRGTCBlockWidth);
+ bytes_required *= base::CheckDiv(
+ base::CheckAdd(height, kRGTCBlockHeight - 1), kRGTCBlockHeight);
bytes_required *= 8;
bytes_required *= depth;
break;
case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
- bytes_required = (width + kRGTCBlockWidth - 1) / kRGTCBlockWidth;
- bytes_required *= (height + kRGTCBlockHeight - 1) / kRGTCBlockHeight;
+ bytes_required = base::CheckDiv(
+ base::CheckAdd(width, kRGTCBlockWidth - 1), kRGTCBlockWidth);
+ bytes_required *= base::CheckDiv(
+ base::CheckAdd(height, kRGTCBlockHeight - 1), kRGTCBlockHeight);
bytes_required *= 16;
bytes_required *= depth;
break;
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.
References
On This Page