fix: validate ClusterBits and BlocksInImage; fix uint32 overflow in getGDGT#2001
Open
GusFromSpace wants to merge 1 commit intogoogle:mainfrom
Open
fix: validate ClusterBits and BlocksInImage; fix uint32 overflow in getGDGT#2001GusFromSpace wants to merge 1 commit intogoogle:mainfrom
GusFromSpace wants to merge 1 commit intogoogle:mainfrom
Conversation
…etGDGT Three DoS vulnerabilities in VM disk image parsers, all triggered by parsing a maliciously crafted disk image file. QCOW2 (format.go): ClusterBits is read from the image header with no bounds check. The QCOW2 spec limits valid values to 9-21. Without this check, ClusterBits=62 causes make([]byte, 4EB) which panics the runtime. Validation added to both readL1Table and readL2Table. VMDK (vmdk.go): GDsectors, GTsectors, and GTs are uint32 values. Multiplying them before widening to int64 causes overflow, producing a wrapped totalSectors that bypasses the >1<<31 size check. The gdarr allocation overflows for the same reason. Fixed by casting each operand to int64 before multiplication. VDI (vdi.go): BlocksInImage is a uint32 read directly from the image header with no upper bound. make([]uint32, 0x3FFFFFFF) allocates ~4GB. Added a 2M-block cap (2*1024*1024), generous for any real VDI image.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes three Denial-of-Service vulnerabilities in the embedded filesystem extractors for QCOW2, VMDK, and VDI disk image formats. All three are triggered by parsing a maliciously crafted disk image file passed to OSV-SCALIBR.
These were identified and confirmed with working PoC tests by Mesopredator, an autonomous security analysis system. A security report was submitted to Google VRP on 2026-04-23.
QCOW2 — Unbounded ClusterBits allocation → runtime panic
File:
extractor/filesystem/embeddedfs/qcow2/format.goFunctions:
readL1Table,readL2Tableheader.ClusterBitsis read from the image with no bounds check. The QCOW2 spec permits values 9–21 only. WithClusterBits=62,uint64(1) << 62produces a 4-exabyte value passed tomake([]byte, ...), which panics the Go runtime immediately.Fix: Validate
ClusterBitsin range 9–21 at the entry of both functions.VMDK — uint32 overflow bypasses size check in
getGDGTFile:
extractor/filesystem/embeddedfs/vmdk/vmdk.goFunction:
getGDGTGTsectors*GTsis uint32 multiplication. It overflows before being cast toint64, so thetotalBytes > 1<<31bounds check operates on a wrapped value and silently passes. Thegdarrallocation overflows for the same reason, producing a zero-length slice. Any subsequent indexed access panics.Fix: Cast each operand to
int64before multiplication.VDI — Unbounded BlocksInImage allocation → forced multi-GB allocation
File:
extractor/filesystem/embeddedfs/vdi/vdi.goFunction:
convertVDIToRawhdr.BlocksInImageis a uint32 read directly from the image header with no upper bound.make([]uint32, 0x3FFFFFFF)allocates ~4 GB. On memory-constrained hosts or with the maximum uint32 value, the process crashes.Fix: Reject images where
BlocksInImage > 2*1024*1024(2M blocks — well above any real VDI image).Test plan
go test ./extractor/filesystem/embeddedfs/qcow2/...— passesgo test ./extractor/filesystem/embeddedfs/vmdk/...— passesgo test ./extractor/filesystem/embeddedfs/vdi/...— passesIdentified by Mesopredator autonomous security analysis.