Skip to content

Fix DoS via panic in Go GetRootAs functions on short buffers#9039

Open
YLChen-007 wants to merge 1 commit intogoogle:masterfrom
YLChen-007:fix-go-getrootas-panic
Open

Fix DoS via panic in Go GetRootAs functions on short buffers#9039
YLChen-007 wants to merge 1 commit intogoogle:masterfrom
YLChen-007:fix-go-getrootas-panic

Conversation

@YLChen-007
Copy link
Copy Markdown

Summary

Fix a Denial of Service (DoS) vulnerability (CWE-125) in the Go FlatBuffers runtime and code generator. The GetRootAs family of functions panic on buffers shorter than 4 bytes due to missing bounds checks before reading the root UOffsetT, causing complete process termination.

Root Cause

When GetRootAs(buf, offset, fb) is called, it passes buf[offset:] to GetUOffsetT(), which internally calls GetUint32():

func GetUint32(buf []byte) (n uint32) {
    _ = buf[3] // Force one bounds check — PANICS if len(buf) < 4
    ...
}

If the buffer has fewer than 4 bytes remaining after offset, buf[3] triggers an unrecoverable Go panic. Since Go panics crash the entire process unless explicitly recovered, an attacker can crash any Go application processing untrusted FlatBuffers data by sending a single 3-byte payload.

A similar vulnerability in the gRPC deserialization path was previously fixed in PR #8684 by adding a len(data) < SizeUOffsetT check. However, the general-purpose GetRootAs API was left unprotected.

Fix

This PR adds bounds checking to:

  1. go/lib.go (runtime) — All public deserialization entry points:

    • GetRootAs() — checks int(offset)+SizeUOffsetT > len(buf)
    • GetSizePrefixedRootAs() — checks int(offset)+sizePrefixLength+SizeUOffsetT > len(buf)
    • GetSizePrefix() — checks before reading size prefix
    • GetIndirectOffset() — checks before reading indirect offset
    • GetBufferIdentifier() / GetSizePrefixedBufferIdentifier() — checks minimum buffer length
  2. src/idl_gen_go.cpp (code generator) — All flatc-generated GetRootAs<Type>() and GetSizePrefixedRootAs<Type>() functions now include the same bounds check, returning nil on short buffers.

The fix maintains backward API compatibility — no function signatures are changed. Functions silently return zero-values/nil on insufficient data, which is consistent with Go's zero-value semantics and the existing gRPC error handling pattern.

Testing

  • go/lib_test.go — New unit tests covering all short-buffer panic scenarios (nil, empty, 1-3 byte buffers) plus regression tests for valid buffers
  • All existing C++ flattests pass: ALL TESTS PASSED
  • Verified generated Go code contains bounds checks via flatc -g

PoC (Before Fix)

# Server using GetRootAs crashes instantly on receiving 3-byte payload:
# panic: runtime error: index out of range [3] with length 3
python3 -c 'import socket; s=socket.socket(); s.connect(("127.0.0.1",8888)); s.sendall(b"abc")'

Related

@google-cla
Copy link
Copy Markdown

google-cla bot commented Apr 10, 2026

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.

@github-actions github-actions bot added golang c++ codegen Involving generating code from schema labels Apr 10, 2026
Add bounds checking to GetRootAs, GetSizePrefixedRootAs, GetSizePrefix,
GetIndirectOffset, and GetBufferIdentifier in go/lib.go to prevent
panics when called with buffers shorter than SizeUOffsetT (4 bytes).

Also update the flatc Go code generator (idl_gen_go.cpp) so that all
generated GetRootAs<Type> and GetSizePrefixedRootAs<Type> functions
include the same bounds check, returning nil on short buffers instead
of panicking.

This extends the fix previously applied only to the gRPC path
(grpc.go, PR google#8684) to the general-purpose API.
@YLChen-007 YLChen-007 force-pushed the fix-go-getrootas-panic branch from 9e254ff to b5b9929 Compare April 12, 2026 02:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ codegen Involving generating code from schema golang

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant