Skip to content
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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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