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

Fix double-drop in Vec::from_iter(vec.into_iter()) specialization when items drop during panic #83629

Closed
wants to merge 3 commits into from

Conversation

the8472
Copy link
Member

@the8472 the8472 commented Mar 29, 2021

This fixes the double-drop but it leaves a behavioral difference compared to the default implementation intact: In the default implementation the source and the destination vec are separate objects, so they get dropped separately. Here they share an allocation and the latter only exists as a pointer into the former. So if dropping the former panics then this fix will leak more items than the default implementation would. Is this acceptable or should the specialization also mimic the default implementation's drops-during-panic behavior?

Fixes #83618

@rustbot label T-libs-impl

@rustbot rustbot added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Mar 29, 2021
@rust-highfive
Copy link
Collaborator

r? @m-ou-se

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 29, 2021
@m-ou-se
Copy link
Member

m-ou-se commented Apr 1, 2021

Is this acceptable

Yes.

@bors r+

Thanks!

@bors
Copy link
Contributor

bors commented Apr 1, 2021

📌 Commit 421f5d2 has been approved by m-ou-se

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 1, 2021
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 1, 2021
…r=m-ou-se

Fix double-drop in `Vec::from_iter(vec.into_iter())` specialization when items drop during panic

This fixes the double-drop but it leaves a behavioral difference compared to the default implementation intact: In the default implementation the source and the destination vec are separate objects, so they get dropped separately. Here they share an allocation and the latter only exists as a pointer into the former. So if dropping the former panics then this fix will leak more items than the default implementation would. Is this acceptable or should the specialization also mimic the default implementation's drops-during-panic behavior?

Fixes rust-lang#83618

`@rustbot` label T-libs-impl
@the8472
Copy link
Member Author

the8472 commented Apr 1, 2021

Since the associated issue is labeled critical, should this go into beta too?

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 2, 2021
…r=m-ou-se

Fix double-drop in `Vec::from_iter(vec.into_iter())` specialization when items drop during panic

This fixes the double-drop but it leaves a behavioral difference compared to the default implementation intact: In the default implementation the source and the destination vec are separate objects, so they get dropped separately. Here they share an allocation and the latter only exists as a pointer into the former. So if dropping the former panics then this fix will leak more items than the default implementation would. Is this acceptable or should the specialization also mimic the default implementation's drops-during-panic behavior?

Fixes rust-lang#83618

`@rustbot` label T-libs-impl
let _ = v.into_iter().take(0).collect::<Vec<_>>();
}));

assert_eq!(unsafe { DROP_COUNTER }, 1);
Copy link
Member

Choose a reason for hiding this comment

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

Does this test ensure to eventually actually free the memory that was "leaked" as part of the "panic during drop"?

If not, this would be a problem for running the test in Miri -- to ensure that the standard library is memory-leak-free, Miri errors. That's why other tests like this that already exist explicit free the "leaked" memory after the test is done.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it doesn't free. Can you point to a test that does the explicit free so I can steal from that?

Copy link
Member

Choose a reason for hiding this comment

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

I think most tests just avoid having a Box, so even if desturctors don't get called, there's no memory leak -- the DROP_COUNTER is usually enough to check that everything is all right.

I thought there were also tests that used manual "late" deallocation of the Box, but cannot find any... do you think checking DROP_COUNTER is sufficient?

Copy link
Member Author

Choose a reason for hiding this comment

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

That should be possible, yeah. I took the reproducer from #83629 which relied on a double-free to trigger malloc errors and converted it into a test-case.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, that won't do since the vec's storage itself will also get leaked.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, good point!

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 2, 2021
…r=m-ou-se

Fix double-drop in `Vec::from_iter(vec.into_iter())` specialization when items drop during panic

This fixes the double-drop but it leaves a behavioral difference compared to the default implementation intact: In the default implementation the source and the destination vec are separate objects, so they get dropped separately. Here they share an allocation and the latter only exists as a pointer into the former. So if dropping the former panics then this fix will leak more items than the default implementation would. Is this acceptable or should the specialization also mimic the default implementation's drops-during-panic behavior?

Fixes rust-lang#83618

`@rustbot` label T-libs-impl
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 2, 2021
Rollup of 7 pull requests

Successful merges:

 - rust-lang#83065 (Rework `std::sys::windows::alloc`)
 - rust-lang#83478 (rustdoc: Add unstable option to only emit shared/crate-specific files)
 - rust-lang#83629 (Fix double-drop in `Vec::from_iter(vec.into_iter())` specialization when items drop during panic)
 - rust-lang#83673 (give full path of constraint in suggest_constraining_type_param)
 - rust-lang#83755 (Simplify coverage tests)
 - rust-lang#83757 (2229: Support migration via rustfix)
 - rust-lang#83771 (Fix stack overflow detection on FreeBSD 11.1+)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@rust-log-analyzer

This comment has been minimized.

@the8472
Copy link
Member Author

the8472 commented Apr 2, 2021

This needs another approval, I added one more commit to address the miri issue while the rollup was in flight.

@rustbot label -S-waiting-on-bors +S-waiting-on-review

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 2, 2021
@RalfJung
Copy link
Member

RalfJung commented Apr 3, 2021

I'm afraid changing a PR while a rollup is in flight will confuse things a bit.^^ Most of the commits of this one have landed as part of #83790, so I'll close this PR. It would be better to open a new PR, I think.

@RalfJung RalfJung closed this Apr 3, 2021
@RalfJung
Copy link
Member

RalfJung commented Apr 3, 2021

FWIW, here is the anticipated leak -- looks like only one allocation actually leaked?

0.213298   The following memory was leaked: alloc10449836 (Rust heap, size: 16, align: 8) {
0.000075       ╾a10449880[<24771093>]╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
0.000012   }
0.000007   alloc10449880 (deallocated)

@the8472
Copy link
Member Author

the8472 commented Apr 3, 2021

FWIW, here is the anticipated leak -- looks like only one allocation actually leaked?

0.213298   The following memory was leaked: alloc10449836 (Rust heap, size: 16, align: 8) {
0.000075       ╾a10449880[<24771093>]╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
0.000012   }
0.000007   alloc10449880 (deallocated)

That should actually be correct. Without the fix the Box got dropped twice and the vec got dropped once. Now the box gets dropped once and the vec gets leaked.

I'm afraid changing a PR while a rollup is in flight will confuse things a bit.^^ Most of the commits of this one have landed as part of #83790, so I'll close this PR. It would be better to open a new PR, I think.

Eh, git can deal with merging the same branch twice. But ok, I'll make a new PR. I can also add the box again.

@RalfJung
Copy link
Member

RalfJung commented Apr 3, 2021

But ok, I'll make a new PR. I can also add the box again.

Thanks a lot!

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Apr 4, 2021
…r=RalfJung

cleanup leak after test to make miri happy

Contains changes that were requested in rust-lang#83629 but didn't make it into the rollup.

r? `@RalfJung`
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Apr 4, 2021
…r=RalfJung

cleanup leak after test to make miri happy

Contains changes that were requested in rust-lang#83629 but didn't make it into the rollup.

r? ``@RalfJung``
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Apr 4, 2021
…r=RalfJung

cleanup leak after test to make miri happy

Contains changes that were requested in rust-lang#83629 but didn't make it into the rollup.

r? ```@RalfJung```
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 4, 2021
…r=RalfJung

cleanup leak after test to make miri happy

Contains changes that were requested in rust-lang#83629 but didn't make it into the rollup.

r? ````@RalfJung````
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 4, 2021
…r=RalfJung

cleanup leak after test to make miri happy

Contains changes that were requested in rust-lang#83629 but didn't make it into the rollup.

r? `````@RalfJung`````
@cuviper cuviper added this to the 1.53.0 milestone Apr 16, 2021
@cuviper
Copy link
Member

cuviper commented Apr 16, 2021

This PR was cited as the fix for CVE-2021-31162, so I'm nominating it for beta.

@cuviper cuviper added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Apr 16, 2021
@the8472
Copy link
Member Author

the8472 commented Apr 16, 2021

If miri tests are executed for beta builds you'll want #83827 too

@RalfJung
Copy link
Member

No, Miri is nightly-only.

@wesleywiser
Copy link
Member

We discussed this in the compiler team triage meeting this morning and decided to approve for backport.

@wesleywiser wesleywiser added beta-accepted Accepted for backporting to the compiler in the beta channel. beta-nominated Nominated for backporting to the compiler in the beta channel. and removed beta-nominated Nominated for backporting to the compiler in the beta channel. labels Apr 22, 2021
@cuviper cuviper mentioned this pull request Apr 26, 2021
@Mark-Simulacrum Mark-Simulacrum removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Apr 27, 2021
@Mark-Simulacrum Mark-Simulacrum modified the milestones: 1.53.0, 1.52.0 Apr 27, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 27, 2021
[beta] backports

This backports two beta-accepted PRs, fixing CVE-2020-36323 and CVE-2021-31162.

- Fixes API soundness issue in `join()` rust-lang#81728
- Fix double-drop in `Vec::from_iter(vec.into_iter())` specialization when items drop during panic rust-lang#83629
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. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Double free in Vec::from_iter specialization when drop panics
10 participants