A story of leaking uninitialized memory from Fastly

We discussed this vulnerability during Episode 118 on 08 February 2022

A cool bug in H2O’s QUIC implementation leading to disclosing uninitialized memory. Stream data in HTTP/3 comes in an encoding similar to chunked encoding, including an offset in the chain, the data size and teh data itself. The Quicly library which implements Quic provides a callback to H2Os code providing these frames as they arrive, and provides an interface to request the byte ranges that it has received so far. H2O gets these calls backs and tries to create a single contiguous memory block for the received data, resizing as necessary. The problem comes when data arrives out of order creating gaps in the memory that H2O has actually written to. If a frame comes it at say 0x100 and then another at 0x600, the frames between won’t be initalized. Normally of course all these bytes will come in and there won’t be a problem because all the memory will eventually be initialized. One could maliciouslly craft a request that will create these gaps, then by sending a RESET_STREAM frame, terminate the stream and have Quicly just check if it has recieves the right amount of data, and drop all knowledge about the recieved byte ranges. So H2O no longer has any way (apart from tracking it internally) to know which byte ranges in its own contiguous stream have been sent. By getting this request sent along to an endpoint it can disclose memory from the Fastly server about other user’s and their requests.