Skip to content

Bound replicated vector size before resize() - #2893

Open
eGurucharri wants to merge 1 commit into
daid:masterfrom
eGurucharri:fix/replicated-vector-resize-bound
Open

Bound replicated vector size before resize()#2893
eGurucharri wants to merge 1 commit into
daid:masterfrom
eGurucharri:fix/replicated-vector-resize-bound

Conversation

@eGurucharri

Copy link
Copy Markdown
Contributor

Problem

std::vector<T> replication reads a size prefix straight off the network and calls resize() with it before reading a single element — both the generic sp::io::operator>> for std::vector<T> in src/multiplayer/basic.h and the BASIC_REPLICATION_VECTOR macro's Receive case.

A corrupt packet, or a hostile client inside a multiplayer session, can announce a size near UINT32_MAX, forcing a multi-gigabyte allocation before any bounds/data-availability check happens — a memory-exhaustion DoS / crash for whoever processes the packet (client or server).

For contrast, the per-element index in BASIC_REPLICATION_VECTOR's receive loop is already validated against the vector's current size before writing — this is specifically about the unbounded resize() call itself.

Fix

Clamp the announced size to a fixed upper bound (max_replicated_vector_size = 1'000'000) before resizing, logging a warning when a packet exceeds it, in both places that resize from a wire-provided size.

Testing

Built with WARNING_IS_ERROR=1 against a sibling SeriousProton checkout — full clean build succeeds (539/539 targets), no warnings introduced.

I did not add an automated regression test for this — I'm not familiar enough with this codebase's network/replication test setup to know where a targeted test would fit; happy to add one if pointed at the right harness.

std::vector<T> replication (both the generic sp::io operator>> and
BASIC_REPLICATION_VECTOR) resizes to a uint32_t/size_t read directly
off the network before reading a single element. A corrupt or hostile
packet can announce a size near UINT32_MAX, forcing a multi-gigabyte
allocation and crashing/DoS'ing whoever processes the packet.

Clamp to a fixed upper bound (1,000,000 elements) and log a warning
instead of trusting the announced size unconditionally.
@daid

daid commented Jul 22, 2026

Copy link
Copy Markdown
Owner

This smells AI assisted/generated. I don't mind people using AI, but I do ask that if they did that they be up-front about it.

@eGurucharri

Copy link
Copy Markdown
Contributor Author

Hello, I'm Eloy. Yes, that was AI generated, as a little project to learn how to use it in our free time we're doing https://github.com/VaroTv7/espaciokooplagunak.

And a very big part of it basically is based on mixing Empty Epsilon and FoundryVTT, as we wanted to make a game that allows us to roleplay DnD while going on a cool spaceship.

Anyway, as we were advancing there were some small fixes the AI/QA tools found (stuff like this one, or the CSS one, or some dependencies), so we thought it wouldn't hurt to open a few PRs upstream.

But of course it's up to you guys if you want to accept them or not, if it's okay we can keep sending those upstream, and if not we'll just tell the AI to not do that.

Best regards!

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.

2 participants