Uh oh!
There was an error while loading. Please reload this page.
memrchr: Correct aligned offset computation - #35969
Conversation
rust-highfive
commented
Aug 24, 2016
r? @aturon (rust_highfive has picked a reviewer for you, use r? to override) |
The memrchr fallback did not compute the offset correctly. It was intentioned to land on usize-aligned addresses but did not. This was suspected to resulted in a crash on ARMv7 platform! This bug affected non-linux platforms. I think like this, if we have a slice with pointer `ptr` and length `len`, we want to find the last usize-aligned offset in the slice. The correct computation should be: For example if ptr = 1 and len = 6, and size_of::<usize>() is 4: [ x x x x x x ] 1 2 3 4 5 6 ^-- last aligned address at offset 3 from the start. The last aligned address is ptr + len - (ptr + len) % usize_size. Compute offset from the start as: offset = len - (ptr + len) % usize_size = 6 - (1 + 6) % 4 = 6 - 3 = 3. I believe the function's return value was always correct previously, if the platform supported unaligned addresses.
| @@ -209,7 +209,7 @@ mod fallback { | |||
| let end_align = (ptr as usize + len) & (usize_bytes - 1); | |||
There was a problem hiding this comment.
Preexisting, but this uses size_of to calculate usize_bytes, but alignment of usize on a system is not size_of::<usize> but rather align_of::<usize>? Seems like a pessimisation?
There was a problem hiding this comment.
It doesn't seem like a big deal. I prefer a separate PR to deal with this. Let's have the fix here be minimal, especially if we backport it.
nagisa
commented
Aug 24, 2016
LGTM, but it took me some 10 mins in a distraction-ful environment to figure out the offset calculation. I think a bug like this would’ve been obvious with a plain conditional as I proposed above. |
bluss
commented
Aug 24, 2016
Thank you for contributing the concentration! I agree that the conditional is better that way, will amend. |
This makes the critical calculation easier to understand.
bluss
commented
Aug 24, 2016
@bors r=nagisa |
bors
commented
Aug 24, 2016
📌 Commit 8295c50 has been approved by |
bors
commented
Aug 26, 2016
⌛ Testing commit 8295c50 with merge 0f1f6ce... |
bors
commented
Aug 26, 2016
💔 Test failed - auto-win-gnu-32-opt-rustbuild |
bluss
commented
Aug 26, 2016
|
sophiajt
commented
Aug 26, 2016
@bors retry |
bors
commented
Aug 27, 2016
memrchr: Correct aligned offset computation The memrchr fallback did not compute the offset correctly. It was intentioned to land on usize-aligned addresses but did not. This was suspected to have resulted in a crash on ARMv7! This bug affected non-linux platforms. I think like this, if we have a slice with pointer `ptr` and length `len`, we want to find the last usize-aligned offset in the slice. The correct computation should be: For example if ptr = 1 and len = 6, and `size_of::<usize>()` is 4: ``` [ x x x x x x ] 1 2 3 4 5 6 ^-- last aligned address at offset 3 from the start. ``` The last aligned address is ptr + len - (ptr + len) % usize_size. Compute offset from the start as: offset = len - (ptr + len) % usize_size = 6 - (1 + 6) % 4 = 6 - 3 = 3. I believe the function's return value was always correct previously, if the platform supported unaligned addresses. Fixes#35967
bors
commented
Aug 27, 2016
Nominating for beta: It's a crashing bug affecting std::io::stdout (common libstd feature) on a minority platform (discovered on ARMv7 on android). Neither x86, x86-64, nor cfg(linux) platforms are affected. |
bluss
commented
Aug 29, 2016
Fix was verified by #35967 (comment) |
alexcrichton
commented
Sep 12, 2016
Libs decided to accept for backport. |
The memrchr fallback did not compute the offset correctly. It was
intentioned to land on usize-aligned addresses but did not.
This was suspected to have resulted in a crash on ARMv7!
This bug affected non-linux platforms.
I think like this, if we have a slice with pointer
ptrand lengthlen, we want to find the last usize-aligned offset in the slice.The correct computation should be:
For example if ptr = 1 and len = 6, and
size_of::<usize>()is 4:The last aligned address is ptr + len - (ptr + len) % usize_size.
Compute offset from the start as:
offset = len - (ptr + len) % usize_size = 6 - (1 + 6) % 4 = 6 - 3 = 3.
I believe the function's return value was always correct previously, if
the platform supported unaligned addresses.
Fixes#35967