Skip to content

[Swift] Verifier accepts truncated scalar vectors leading to OOB read/write and RCE #9082

@alimezar

Description

@alimezar

Summary

The Swift Verifiable.verifyRange helper used by getCheckedRoot accepts malformed FlatBuffers whose scalar-vector element count does not match the available payload bytes. After verification reports success, the generated accessors and mutators read and write past ByteBuffer.capacity.

Originally reported privately via Google IssueTracker (issue 510740173, non-public). Filing here for a public reference and to link the fix.

Affected

  • Language: Swift
  • File: swift/Sources/FlatBuffers/Verifiable.swift
  • Entry point: getCheckedRoot(byteBuffer:) for any table containing a scalar vector with element size > 1 byte (e.g. [long], [int], [double], [ulong]).

Root cause

verifyRange passes the vector's declared element count directly to rangeInBuffer as if it were a byte count. For any scalar vector whose element size is greater than one byte, the declared length only has to fit byteBuffer.capacity bytes after the vector header, instead of count * elementSize bytes. A buffer declaring N elements while containing only N raw bytes of payload therefore passes verification.

Once verification succeeds, the generated typed accessors index the vector at start + i * MemoryLayout<T>.size, which can land arbitrarily far past the end of the buffer. The corresponding mutators perform out-of-bounds writes.

Impact

  • Out-of-bounds memory disclosure via generated read accessors.
  • Out-of-bounds memory corruption via generated mutators.
  • Reachable from any code path that calls getCheckedRoot on attacker-controlled bytes, i.e. exactly the API intended to make untrusted input safe.

Fix

Multiply the declared element count by MemoryLayout<T>.size with overflow detection, and pass the resulting byte size to rangeInBuffer, so truncated scalar vectors are rejected at verification time before any unsafe generated access can occur.

Pull request: #9081

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions