tracing: use ManuallyDrop instead of mem::forget (#2765)

The current code is UB and LLVM could choose to reuse the stack slot causing a UAF.

## Motivation

UB is bad.

## Solution

Don't do that.
This commit is contained in:
Manish Goregaokar 2023-10-18 16:44:33 -07:00 committed by Eliza Weisman
parent 4b99457c87
commit 20a1762b3f
No known key found for this signature in database
GPG Key ID: F9C1A595C3814436

View File

@ -5,7 +5,7 @@ use crate::{
use core::{ use core::{
future::Future, future::Future,
marker::Sized, marker::Sized,
mem::{self, ManuallyDrop}, mem::ManuallyDrop,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
@ -359,12 +359,11 @@ impl<T> Instrumented<T> {
/// ///
/// Note that this drops the span. /// Note that this drops the span.
pub fn into_inner(self) -> T { pub fn into_inner(self) -> T {
// To manually destructure `Instrumented` without `Drop`, we save // To manually destructure `Instrumented` without `Drop`, we
// pointers to the fields and use `mem::forget` to leave those pointers // move it into a ManuallyDrop and use pointers to its fields
// valid. let this = ManuallyDrop::new(self);
let span: *const Span = &self.span; let span: *const Span = &this.span;
let inner: *const ManuallyDrop<T> = &self.inner; let inner: *const ManuallyDrop<T> = &this.inner;
mem::forget(self);
// SAFETY: Those pointers are valid for reads, because `Drop` didn't // SAFETY: Those pointers are valid for reads, because `Drop` didn't
// run, and properly aligned, because `Instrumented` isn't // run, and properly aligned, because `Instrumented` isn't
// `#[repr(packed)]`. // `#[repr(packed)]`.