New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update operations truncate the provided user_data to 32bit on 32bit builds. #490
Comments
What cases on 32-bit wants to put a 64-bit address into what should be a user pointer? Looking at this more closely, I'm a bit puzzled on what commands are involved here? Off the top of my head I don't recall any commands actually not using that for an actual user address, in which case how could that even work to put a non-valid 32-bit pointer in there? Is this just a timeout command (and/or update) issue? Are there others? From a quick look, looks like timeout_update and timeout_remove are the only problematic ones here. |
And if so, why don't we just do:
and avoid any kind of breakage related to this. |
If we're running on 32-bit, with the cast that io_uring_prep_rw() does, we lose the top 32 bits of the user_data for the timeout remove and update commands. If the application also uses a full 64-bit value for the original timeout user_data, then we cannot find the timeout to update. Link: #490 Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Well the documentation says that, The previously submitted sqe |
Yeah, you are right, there are a few more. I'll take a look at those. |
For the commands where we use it as a lookup key, then we don't want to rob 32-bit applications from the potential of using the full 64-bit type. This includes commands like: poll_remove, poll_update, prep_cancel Also provide 64-bit u64 types of the sqe set data and the cqe get data helpers, along with a define that allows applications to check for the presence of it. NOTE: this may trigger compile warnings in applications that currently use these helpers, which is also why a few test cases had to get adapted. The fixup is trivial, and the above define can help applications check if one or the other is the current one. Link: #490 Reported-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
The internal structures use
__u64
both foraddr
field and foruser_data
fields, which is nice as they are usually matched against each other for update operations.However, the internal
io_uring_prep_rw
function takes avoid * addr
, (but then casts it back to__u64
), Several other public API functions, are doing truncation, such asio_uring_prep_poll_update
, which takesvoid* old_user_data
/void* new_user_data
, or even worse,io_uring_prep_timeout_update
which takes a__u64 user_data
to match the timeout that needs updating but internally casts it tounsigned long
/void *
when callingio_uring_prep_rw
.Overall, this makes the
liburing
API fairly unusable on 32bit for such operations, as theaddr
field get truncated, and the user needs to fill the sqe fields by hand. This is pretty inconvenient for writing portable code, and the API should make sure no unnecessary truncation happens.The text was updated successfully, but these errors were encountered: