Skip to content

reliable 1.4.4: fragment reassembly survives an allocator that returns NULL

Choose a tag to compare

@rowan-claude rowan-claude released this 13 Sep 20:41
d4b6fe0

An allocator that returns NULL while reassembling a fragmented packet now fails the fragment, not the process. reliable_endpoint_receive_packet guarded its reassembly buffer allocation with an assert alone: under RELIABLE_RELEASE the assert compiles away and the library dereferenced NULL, and under RELIABLE_DEBUG — the default whenever NDEBUG is absent — the default assert handler called exit(1). This was never confined to a caller-supplied allocator: an endpoint created without one gets reliable_default_allocate_function, a bare malloc, so any build on a machine where malloc can fail was exposed, even though reliable.h documents a NULL return from allocate_function as a supported outcome and endpoint creation already honors it. The receive path now honors it too: it removes the reassembly entry it had just inserted, counts the fragment in RELIABLE_ENDPOINT_COUNTER_NUM_FRAGMENTS_INVALID, and returns, so the endpoint stays up and the packets around it are unaffected. That counter's meaning widens here: it has counted fragments a peer sent that the endpoint could not use, and now also counts a fragment dropped to a local allocation failure, so a reader watching it for a misbehaving peer should read a rise under memory pressure as its own cause. The class is availability: a peer able to drive an endpoint to its allocation limit could end the process, and can now only cost it fragments. Nothing on the wire changes, no symbol changes, and reassembled bytes are unchanged. test_fragment_reassembly_alloc_failure covers it red-first — without the fix it stops at the old assert. Found by an outside security review.