Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

memrchr: Correct aligned offset computation #35969

Merged
merged 2 commits into from
Aug 27, 2016

Conversation

bluss
Copy link
Member

@bluss bluss commented Aug 24, 2016

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

@rust-highfive
Copy link
Collaborator

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.
@bluss bluss force-pushed the memrchr-alignment branch from fed896d to d1ecee9 Compare August 24, 2016 17:05
@@ -209,7 +209,7 @@ mod fallback {
let end_align = (ptr as usize + len) & (usize_bytes - 1);
Copy link
Member

Choose a reason for hiding this comment

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

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

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
Copy link
Member

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
Copy link
Member Author

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
Copy link
Member Author

bluss commented Aug 24, 2016

@bors r=nagisa

@bors
Copy link
Contributor

bors commented Aug 24, 2016

📌 Commit 8295c50 has been approved by nagisa

@bors
Copy link
Contributor

bors commented Aug 26, 2016

⌛ Testing commit 8295c50 with merge 0f1f6ce...

@bors
Copy link
Contributor

bors commented Aug 26, 2016

💔 Test failed - auto-win-gnu-32-opt-rustbuild

@bluss
Copy link
Member Author

bluss commented Aug 26, 2016

failures:

---- [incremental] incremental\ich_method_call_trait_scope.rs stdout ----
    thread '[incremental] incremental\ich_method_call_trait_scope.rs' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 3, message: "The system cannot find the path specified." } }', C:\bot\slave\auto-win-gnu-32-opt-rustbuild\build\src\libcore\result.rs:783
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    [incremental] incremental\ich_method_call_trait_scope.rs

@sophiajt
Copy link
Contributor

@bors retry

@bors
Copy link
Contributor

bors commented Aug 27, 2016

⌛ Testing commit 8295c50 with merge 1194695...

bors added a commit that referenced this pull request 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 bors merged commit 8295c50 into rust-lang:master Aug 27, 2016
@bluss bluss deleted the memrchr-alignment branch August 27, 2016 18:47
@bluss bluss added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Aug 27, 2016
@bluss
Copy link
Member Author

bluss 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
Copy link
Member Author

bluss commented Aug 29, 2016

Fix was verified by #35967 (comment)

@nikomatsakis nikomatsakis added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Sep 1, 2016
@alexcrichton
Copy link
Member

Libs decided to accept for backport.

@alexcrichton alexcrichton added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Sep 12, 2016
@brson brson removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Sep 16, 2016
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants