Skip to content

Limit the element count of fixed-length lists#2537

Open
eyupcanakman wants to merge 1 commit into
bytecodealliance:mainfrom
eyupcanakman:fix/fixed-length-list-size-limit-2416
Open

Limit the element count of fixed-length lists#2537
eyupcanakman wants to merge 1 commit into
bytecodealliance:mainfrom
eyupcanakman:fix/fixed-length-list-size-limit-2416

Conversation

@eyupcanakman

Copy link
Copy Markdown
Contributor

Fixed-length lists were only checked for zero elements, with no upper bound, so a list of up to 4294967295 elements passed validation. The count then flows to consumers and overflows their canonical ABI size calculations. Cap the element count at 1 Gi, the limit suggested on the issue.

Closes #2416.

Fixed-length lists were only checked for zero elements, with no upper bound, so a list of up to 4294967295 elements passed validation. The count then flows to consumers and overflows their canonical ABI size calculations. Cap the element count at 1 Gi, the limit suggested on the issue.

Closes bytecodealliance#2416.
@eyupcanakman eyupcanakman requested a review from a team as a code owner June 6, 2026 12:07
@eyupcanakman eyupcanakman requested review from fitzgen and removed request for a team June 6, 2026 12:07
@eyupcanakman

Copy link
Copy Markdown
Contributor Author

While here I noticed this bounds the count rather than the resulting byte size. SizeAlign in wit-parser and wit-dylib still assume a fixed-length list's size fits a u32/usize, so a list<u64> near the cap or a nested list overflows. That path already exists on main, independent of this change. I can open a separate issue or PR for it if that's worth doing.

@alexcrichton

Copy link
Copy Markdown
Member

Thanks for the PR, but yeah what I was looking for in the original issue was a bound on the byte-size of the list so downstream consumers don't have to worry as much about integer overflow. In that sense I think the check here should be on the in-memory-byte-size rather than the number of elements.

@eyupcanakman

Copy link
Copy Markdown
Contributor Author

Switched the check to the in-memory byte size, element ABI size times length, with a 1 GiB limit. Two questions before I finish it.

Computing the element size means walking the element type, so a deeply nested chain of fixed-length lists can blow the stack. Want the size stored per type next to the existing TypeInfo, or is the walk fine?

The limit also rejects wit-deep-list.wit now, since its outer type is 4 GiB. Is that the behavior you want or should nesting be bounded differently?

@alexcrichton

Copy link
Copy Markdown
Member

The walk should be fine, yeah, we've got other mechanisms of limiting the depth of a type for this exact reason. Most of wasm-tools/external tooling will walk the structure of a type recursively so the maximum depth is bounded. If you're actually blowing the stack though and this isn't hypothetical that may mean we have a hole in our checks somewhere...

Otherwise though yeah feel free to change the wit-deep-list.wit type, no need to keep that working exactly as-is

@eyupcanakman

Copy link
Copy Markdown
Contributor Author

Confirmed it's real, not hypothetical. A nested fixed-length-list chain overflows the stack on the binary validate path around 80k deep where the element-count version was fine, and nothing bounds that depth (MAX_WASM_SUBTYPING_DEPTH only covers core types), so option/result/map nesting can hit it too. Want me to add a depth limit on those arms or cache each type's size?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow up from wasmtime: Check reasonable sizes for fixed-size-lists in validator

2 participants