Skip to content

Worker: Ensure 4-byte alignment for network packet receive buffers and test buffers to avoid UB (undefined behavior)#1756

Open
ibc wants to merge 19 commits intov3from
align-buffers
Open

Worker: Ensure 4-byte alignment for network packet receive buffers and test buffers to avoid UB (undefined behavior)#1756
ibc wants to merge 19 commits intov3from
align-buffers

Conversation

@ibc
Copy link
Member

@ibc ibc commented Mar 20, 2026

Details

  • Fixes Must fix misaligned byte access in RTP, STUN and SCTP packets #1755. All info in that ticket.
  • Make test-asan-undefined/thread fail if a warning shows up instead of exiting with success, so from now own CI will fail if there is some UB problem (all them are fixed in this PR).
  • Use -O3 in ASAN checks and fuzzer to not hide UB problems.

More info

What is the real design problem we have? We obtain RTP, ICE, SCTP, etc. packets from the network and store those bytes in a buffer (this happens in UdpSocketHandler.cpp, etc).

Later we do a cast of that buffer to RTP::Packet or other classes/structs and here the UB problems may happen.

Undefined behavior (UB) occurs when a program performs an operation, such as accessing a misaligned memory address, that the C++ standard does not define, potentially leading to crashes or incorrect results.

First, those classes/structs have members of different size (uint8_t, uint16_t, sometimes fields of uint32_t, etc). The whole struct will have an alignment that corresponds to the bigger field, so if the class/struct has a uint32_t the whole struct has alignment 4 (4 bytes).

Second, when we create the read buffer (the static one) such a buffer maybe assigned a memory position that is NOT aligned to 4 bytes. In that case, when we later cast the buffer to a RTP::Packet, when we do packet->GetXxxx() we are not accessing through a 4 bytes aligned struct anymore. In som archs this produces SIGBUS or undefined behavior (we may read unexpected bytes instead of the intended ones).

The solution in this PR consists on forcing all read buffers to be in positions of the memory that are aligned to 4 bytes because we know that all our RTP, STUN, RTCP, SCTP, etc. classes/structs are aligned to maximum 4 bytes (there are no uint64_t fields in any of them.

Other than that we are safe because all RTP, RTCP, STUN and SCTP structs are defined to be aligned in their RFCs (on purpose) so they all have alignment of 4 bytes (largest field in any of those structs is 32 bits so 4 bytes so 4).

So there are two different things here:

  1. Access to aligned memory. This requires that local variables where we store received packets (that later we cast to RTP, RTCP, STUN, SCTP structs/classes) are in positions of memory multiple of 4. We get this by declaring all those buffers with alignas(4).
  2. Access to not aligned fields in our structs. Imagine a struct has a uint8_t foo field followed of uint16_t bar. In this case the struct is aligned to 2 bytes (the largest field in the struct) so some archs may add padding of 1 byte after foo to make the total size of the struct be 4 (1 byte of foo + 1 byte of padding + 2 bytes of bar). Then if you cast a buffer with data received from the network into a local variable myStructVar (no matter it's declared with alignas(4) because that's irrelevant here) then you may have problems in some archs if you do myStructVar.bar because you may end accessing the 3rd and 4th bytes of the buffer instead of the 2nd and 3rd as expected, so undefined behavior (UB) or even a SIGBUS in some archs.

As said above we are fine because all the structs we use are aligned to 4 bytes on purpose in their RFCs.

However, the proper way to go would be that we completely avoid casting buffers with received bytes to our classes or structs. That's bad by design. AFAIS modern implementations do a memcpy of the buffer into an struct once they know which kind of packet is. Pseudo-code:

RTP::PacketHeader rtpHeader{};

memcpy(&rtpHeader, readBuffer, readLen);

This way, it's 100% guaranteed that the content in the read buffer is properly copied to rtpHeader because it includes all needed padding required by the struct design (its fields). However, I'm not sure this is valid in case we need to send such a packet in the wire since of course we MUST NOT send padding bytes within a RTP packet...

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

ibc and others added 6 commits March 21, 2026 15:02
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@ibc ibc requested a review from jmillan March 21, 2026 15:06
@ibc ibc marked this pull request as ready for review March 21, 2026 15:07
@ibc ibc changed the title Worker: Ensure 4-byte alignment for network packet receive buffers and test buffers to avoid undefined behavior Worker: Ensure 4-byte alignment for network packet receive buffers and test buffers to avoid UB (undefined behavior) Mar 21, 2026
@ibc
Copy link
Member Author

ibc commented Mar 21, 2026

I've tested this branch in macOS and Linux (test.mediasoup.org) and it works fine. Nothing is broken and we are now ready to run mediasoup in exotic architectures that require strict alignment when accessing unit16 or unit32 fields from memory referenced by pointers.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Must fix misaligned byte access in RTP, STUN and SCTP packets

1 participant