fix(io_uring): remove type-punning UB in buffer→iovec conversion (#291)#294
Merged
mvandeberg merged 1 commit intoJun 30, 2026
Merged
Conversation
…alliance#291) The io_uring backend declared `iovec iovecs[]` storage, then `reinterpret_cast` it to `capy::mutable_buffer*` so `copy_to` could populate it, and later handed the same storage to the kernel as `iovec`. Even with layout-compatible types this is undefined behavior: no `mutable_buffer` object is ever created in that storage, and `mutable_buffer` is not an implicit-lifetime type, so `std::start_lifetime_as_array` cannot rescue it either. Add a `copy_to_iovec` helper that copies into a real `mutable_buffer` scratch array and then translates field by field into the caller's `iovec` array — the same safe pattern the reactor and posix backends already use, factored into one place since io_uring had 14 call sites. Replace all 14 `reinterpret_cast` sites across io_uring_types.hpp, io_uring_file_ops.hpp, io_uring_dgram_ops.hpp, and io_uring_socket_ops.hpp. Also fix the buffer_param docstring, whose two `@code` examples demonstrated the same `reinterpret_cast<iovec*>` pun as "OK"/"CORRECT" — a recurrence trap. They now show the field-by-field copy and a `@note` explaining why the cast is UB.
|
An automated preview of the documentation is available at https://294.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-06-30 19:33:57 UTC |
|
GCOVR code coverage report https://294.corosio.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-06-30 19:44:52 UTC |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The io_uring backend declared
iovec iovecs[]storage, thenreinterpret_castit tocapy::mutable_buffer*socopy_tocould populate it, and later handed the same storage to the kernel asiovec. Even with layout-compatible types this is undefined behavior: nomutable_bufferobject is ever created in that storage, andmutable_bufferis not an implicit-lifetime type, sostd::start_lifetime_as_arraycannot rescue it either.Add a
copy_to_iovechelper that copies into a realmutable_bufferscratch array and then translates field by field into the caller'siovecarray — the same safe pattern the reactor and posix backends already use, factored into one place since io_uring had 14 call sites. Replace all 14reinterpret_castsites across io_uring_types.hpp, io_uring_file_ops.hpp, io_uring_dgram_ops.hpp, and io_uring_socket_ops.hpp.Also fix the buffer_param docstring, whose two
@codeexamples demonstrated the samereinterpret_cast<iovec*>pun as "OK"/"CORRECT" — a recurrence trap. They now show the field-by-field copy and a@noteexplaining why the cast is UB.