ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.71k stars 2.47k forks source link

coercion of mutable pointers' child type causes a soundness issue #20738

Open Fri3dNstuff opened 1 month ago

Fri3dNstuff commented 1 month ago

Zig Version

0.14.0-dev.367+a57479afc

Steps to Reproduce and Observed Behavior

Attempt to compile the following code:

pub fn main() void {
    const n: u8 align(2) = 42;
    const m: u8 align(1) = 0;

    var t: *align(2) const u8 = &n;
    var u: *align(1) const u8 = &m;
    _ = .{ &t, &u };

    const pt: **align(2) const u8 = &t;
    const pu: **align(1) const u8 = pt; // this coercion is bad!

    pu.* = u;
    // oh no! we've stored an align(1) value in a
    // location that expects to hold an align(2) value
}

The code compiles without errors.

Expected Behavior

The code should have triggered a compilation error.

A mutable pointer to (one / many / slice / C) a type T can coerce into a mutable pointer of type U without soundness problems if-and-only-if:

These are, I believe, the most liberal coercion rules that do not result in soundness problems - I will leave the discussion about whether Zig should be this liberal with its coercion rules to another issue.

rohlem commented 1 month ago

It's already noted in the issue text, but important to note that coercion of pointers-to-const *const *align(2) T -> *const *align(1) T can be allowed. We only need to prevent it when the target pointer-to-mutable broadens the set of valid pointee values.