prevent deref coercions in pin!#153457
Conversation
|
r? @jieyouxu rustbot has assigned @jieyouxu. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
I expect this needs crater, so: @bors try |
This comment has been minimized.
This comment has been minimized.
prevent deref coercions in `pin!`
092ecb8 to
8f93fc9
Compare
|
Just realized I could format things more cleanly (diff). This shouldn't affect the correctness of the try build. |
|
A more explicit approach could be to do something like: super let mut pinned = $value;
#[allow(unreachable_code)]
'p: {
fn unreachable_type_constraint<'a, T>(_: T) -> Pin<&'a mut T> {
unreachable!()
}
break 'p unsafe { Pin::new_unchecked(&mut pinned) };
unreachable_type_constraint(pinned)
} |
|
So that's how to add types to macros! Funky idiom, but I do prefer the explicitness of actually having types, yeah. I think that'd be less likely to break inference too if anything's started relying on it; iirc type expectations are propagated from the block to the break expression (via the block's coercion target type). But it's fine because we'll encounter an error instead of silently adding a coercion if things don't match up.. I think. Would you prefer to make your own PR @eggyal, or should I just work that into this one? I'm not a library reviewer so I can't say which would be preferable from that perspective, but from the perspective I do have, I think adding a type constraint is a better fix. |
|
By all means work it into this one. This idiom was originally suggested to me by lcnr some years ago, so I claim no credit for it! |
|
this change requires someone from libs team to be approved, so i'm reassigning r? libs |
8f93fc9 to
524b11d
Compare
|
Went ahead with the unreachable type constraint version of this (diff). There's unfortunately a bit of a diagnostics regression due to the extra type checking. I still think it's worth the lower likelihood of breakage, but it's a tradeoff. I'll be firing off a fresh try build, but if the diagnostics are a sticking point, maybe it'd be worth comparing crater results for both approaches? |
|
@bors try |
This comment has been minimized.
This comment has been minimized.
prevent deref coercions in `pin!`
|
I'll crater the type constraint approach first since that's my preferred quick fix at the moment. Also going to try re-running pr-check-2. It never restarted after being canceled it looks like? |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
I'm not yet convinced that this approach is 100% sound. Although I think it would be a good idea to do this fix even if it's not 100% sound, since any soundness exploit of this would be significantly more convoluted than the current exploit. Given a value
I am not sure whether there exist types Edit: Added two more bullet points Edit 2: Changed a requirement into the Unpin requirement. |
This comment has been minimized.
This comment has been minimized.
|
@rustbot review |
|
Okay, so reading over the issue and this thread, I think the current approach is okay. I'm not sure @theemathas's comment is applicable. I think there is an additional requisite that the I was attempting to actually create a reproducer. It is definitely possible to have Some info on my experimentationI have the start of a reproducer at https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=a3589e147b0b337b259a8f01da53fd79 I'm not entirely sure why we're getting a mismatched types error. I expected that the output would coerce first and then the arguments, so not sure what's going on. All in all though, I think what we can do is fcp merge this for types. I don't know that I'd quite be happy to close the issue (because it still may be possible to exploit this), but this gets us much closer to soundness at the very least. |
@jackh726 This is not true. If |
This is true.
This is not. This playground gets similarly close, just differently. In this, both Actually, I think the most constrained rule to satisfy is the
For a deref coercion to happen, I'm not sure if I've missed something, but I am feeling fairly confident that the change in this PR is always sound w.r.t. "possible" coercions. I think this analyses does lead to constraints, which is that:
|
|
Alright, to move this forward: I think we should just merge this. I'm a little on the fence of whether or not this needs an FCP. My gut feeling is "typically, seems like something we'd FCP" - that's probably on libs? I think types is probably a better reviewer - which I have (and I think @theemathas has thought through this a bunch too), but ultimately this is lib's territory. However, that being said, this feels more like a "bug fix" for unintended behavior, than anything. So I'm more inclined to just merge without FCP (especially given that crater is clean). As far as #153438, technically that could be closed once this is merged, since the reported unsoundness is gone. However, given the theoretical concern raised by @theemathas, my instinct is to leave it open even after merging this PR. Then, to ensure that issue doesn't stall open, I think a useful process here might be to This lets us merge this and fix at least the known unsoundness - and puts us on a concrete path to close the issue itself. @dianne does this seem reasonable to you? If so, r=me in a day or so (to give people time to respond). |
524b11d to
5276fcd
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
I'm not familiar with T-libs or T-libs-api procedure, so I couldn't say there. The process I'm used to for language bug fixes is to get team approval via Leaving #153438 open here and closing it via types FCP sounds reasonable to me! I've changed the description so it shouldn't automatically be closed. Looking over the diagnostics again, I'm still not happy with how adding the extra function call affected those, but I think I've convinced myself that those are issues with the diagnostics, rather than the macro idiom. I can try and open a separate PR to make One last change, also: I've finally moved the function with the type signature of |
…=Mark-Simulacrum,jackh726 prevent deref coercions in `pin!` Mitigates rust-lang#153438 using a (hopefully temporary!) typed macro idiom to ensure that when `pin!` produces a `Pin<&mut T>`, its argument is of type `T`. See rust-lang#153438 (comment) for my ideas on how this could be changed in the future.
…uwer Rollup of 15 pull requests Successful merges: - #152995 (ACP Implementation of PermissionsExt for Windows ) - #153457 (prevent deref coercions in `pin!`) - #155250 (Windows: Cache the pipe filesystem handle) - #155574 (Move `std::io::RawOsError` to `core::io`) - #155757 (macro_metavar_expr_concat: explain why idents are invalid) - #155823 (miri subtree update) - #155693 (Suggest enclosing format string with `""` under special cases) - #155707 (Fix minor panic-unsoundness in CString::clone_into) - #155719 (Suggest `.iter()` for shared projections) - #155779 (ssa_range_prop: use `if let` guards) - #155789 (Cleanups to `AttributeExt`) - #155805 (Mention `DEPRECATED_LLVM_INTRINSIC` lint for internal use) - #155806 (Remove the incomplete marker from `impl` restrictions) - #155820 (Avoid improper spans when `...` or `..=` is recovered from non-ASCII) - #155822 (Add default field values to diagnostic FormatArgs)
Rollup merge of #153457 - dianne:no-coercing-in-pin-macro, r=Mark-Simulacrum,jackh726 prevent deref coercions in `pin!` Mitigates #153438 using a (hopefully temporary!) typed macro idiom to ensure that when `pin!` produces a `Pin<&mut T>`, its argument is of type `T`. See #153438 (comment) for my ideas on how this could be changed in the future.
View all comments
Mitigates #153438 using a (hopefully temporary!) typed macro idiom to ensure that when
pin!produces aPin<&mut T>, its argument is of typeT. See #153438 (comment) for my ideas on how this could be changed in the future.