Skip to content

Can bypass #[repr(packed)] checking since rust 1.57 #342

@macpp

Description

@macpp

Since rust 1.57 it is possible to put proc macro attributes after derive (see rust-lang/rust#81119)
so given proc macro crate like that:

use proc_macro::TokenStream;
use syn::{parse_macro_input, parse_quote, ItemStruct};
use quote::quote;

#[proc_macro_attribute]
pub fn add_repr(_:TokenStream, item: TokenStream) -> TokenStream {
    let mut item = parse_macro_input!(item as ItemStruct);
    item.attrs.push(parse_quote!{#[add_repr_hidden]});
    quote!{#item}.into()
}

#[proc_macro_attribute]
pub fn add_repr_hidden(_:TokenStream, item: TokenStream) -> TokenStream {
    let mut item = parse_macro_input!(item as ItemStruct);
    item.attrs.push(parse_quote!{#[repr(packed)]});
    quote!{#item}.into()
}

and following usage :

#[pin_project]
#[add_repr]
pub struct Test {
    x: i32
}

__PinProjectInternalDerive won't notice that at the end of the expansion there is #[repr(packed)] on struct
Of course, --cap-lints=warn is still required to actually compile it
I'm not sure how probable it is to trigger this problem in real code base..

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: related to a bug.C-upstream-bugCategory: This is a bug of compiler or dependencies (the fix may require action in the upstream)I-unsoundA soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions