-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Sorting a Slice Raises an Illegal Instruction Signal #136103
Comments
I believe the @jonathan-gruber-jg's analysis to be accurate as to the cause of the bug. Because of the (abort-based) assert it hits I don't believe there's a security issue, only a potential denial-of-service issue. The reason this only triggers with a large type is because up until 8MB we always allocate a scratch space for let alloc_len = cmp::max(len / 2, cmp::min(len, 8_000_000 / size_of::<T>()); The only way to trigger this bug is if the fn main() {
let n = 127;
let mut objs: Vec<_> =
(0..n).map(|i| [(i % 2) as u8; 125001]).collect();
objs.sort();
} If you try to make
The explanation was done in private communication at the time. I proposed to switch to
I still believe this justification to be sound so I don't believe the |
For the record, this did go through a |
@rustbot claim |
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
…=Mark-Simulacrum Fix off-by-one error causing slice::sort to abort the program Fixes rust-lang#136103. Based on the analysis by `@jonathan-gruber-jg` and `@orlp.`
…=Mark-Simulacrum Fix off-by-one error causing slice::sort to abort the program Fixes rust-lang#136103. Based on the analysis by ``@jonathan-gruber-jg`` and ``@orlp.``
Rollup merge of rust-lang#136163 - uellenberg:driftsort-off-by-one, r=Mark-Simulacrum Fix off-by-one error causing slice::sort to abort the program Fixes rust-lang#136103. Based on the analysis by ``@jonathan-gruber-jg`` and ``@orlp.``
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
Fixes rust-lang#136103. Based on the analysis by @jonathan-gruber-jg and @orlp.
…=Mark-Simulacrum Fix off-by-one error causing slice::sort to abort the program Fixes rust-lang#136103. Based on the analysis by ``@jonathan-gruber-jg`` and ``@orlp.``
As the issue title indicates, I have discovered that, in some cases, sorting a slice via
slice::sort
erroneously raises SIGILL (illegal instruction). Below is a minimal test case for the observed behavior.If you run this code in a debugger, you will see that the SIGILL comes from the call to
core::intrinsics::abort
here. That is, something is causingscratch.len()
to be less thanlen
when it shouldn't be.I think I have traced the cause of the problem to how
min_good_run_len
is calculated here. Iflen <= MIN_SQRT_RUN_LEN * MIN_SQRT_RUN_LEN
holds true andlen - len / 2
(which is really justceil(len / 2)
) happens to be<= MIN_SQRT_RUN_LEN
, thenmin_good_run_len
is given the valuelen - len / 2
(which, again, is justceil(len / 2)
). When the functioncreate_run
in the same file cannot find an ascending or descending run of at leastmin_good_run_len
elements, it extracts an unsorted run that extends formin_good_run_len
elements or until the end of the slice/array (whichever is earlier). Later, the functionlogical_merge
in the same file will sort an unsorted run if it and the run with which it is to be merged do not together fit inscratch
.scratch.len()
is at leastfloor(len / 2)
, andfloor(len / 2)
is less thanceil(len / 2)
whenlen
is an odd integer, so a problem arises whenscratch.len()
is equal tofloor(len / 2)
,min_good_run_len
is equal toceil(len / 2)
, andlen
is odd, because, then,logical_merge
might try to sort an unsorted run that cannot fit inscratch
. If my math is correct, this is exactly the situation occurring in my minimal test case.Replacing
len - len / 2
withlen / 2
in the calculation ofmin_good_run_len
would therefore fix the issue, if I am not mistaken. I do not know why the author(s) of the driftsort choselen - len / 2
instead oflen / 2
. Neither the commit (in the original driftsort GitHub repository) where it first appeared (Voultapher/driftsort@dbe1d24) nor the associated pull request (Voultapher/driftsort#39) appears to give an explanation.Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: