Bug 23530 – casting immutable away allowed in safe
Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-12-01T16:42:21Z
Last change time
2024-04-28T14:44:55Z
Keywords
pull, safe
Assigned to
No Owner
Creator
Ate Eskola
Comments
Comment #0 by Ajieskola — 2022-12-01T16:42:21Z
The following code compiles and runs without crash with DMD 2.100.2, flags -preview=dip1000:
------
@safe void main()
{ immutable int x = 5; //alternatively const
auto a = &x;
auto b = &cast() x;
assert(a == b); //passes
*b = 3; //undefined behaviour
}
------
This is a major hole in memory safety, so I'm assigning severity to critical.
Comment #1 by razvan.nitu1305 — 2022-12-02T12:15:35Z
dip1000 is not needed to reproduce this:
@safe void main()
{ immutable int x = 5; //alternatively const
int* b = &(cast()x);
}
This used to fail compilation with a wrong error message: Error: `cast(int)x` is not an lvalue and cannot be modified.
So I assume that at some point it wasn't possible to take the address of a cast. When safe was implemented they probably took this into account and later on when the cast was allowed someone probably forgot to update the safety check.
Comment #2 by dlang-bot — 2022-12-02T13:09:59Z
@RazvanN7 created dlang/dmd pull request #14668 "Fix Issue 23530 - casting immutable away allowed in safe" fixing this issue:
- Fix Issue 23530 - casting immutable away allowed in safe
https://github.com/dlang/dmd/pull/14668
Comment #3 by dlang-bot — 2023-09-10T10:33:13Z
@ntrel created dlang/dmd pull request #15597 "Add CastExp.toLvalue obsolete warning if implicit pointer conversion would fail" fixing this issue:
- Add CastExp.toLvalue -wo warning if implicit pointer conv would fail
From https://dlang.org/spec/expression.html#.define-lvalue
> The following expressions, and no others, are called lvalue expressions or lvalues
...
> cast(U) expressions applied to lvalues of type T when T* is implicitly convertible to U*;
> cast() and cast(qualifier list) when applied to an lvalue.
The first rule was not enforced by dmd.
The second rule contradicts the point of the first rule. It should be
updated to work in the same way.
Fixes Issue 23530 - casting immutable away allowed in safe.
https://github.com/dlang/dmd/pull/15597
Comment #4 by dlang-bot — 2024-03-24T19:57:26Z
@ntrel updated dlang/dmd pull request #16315 "Fix Bugzilla 24434 - Casting away const with cast() is not a @safe lv…" fixing this issue:
- Workaround for safe append
Fixes Bugzilla 23530 - casting immutable away allowed in safe.
https://github.com/dlang/dmd/pull/16315
Comment #5 by dlang-bot — 2024-04-28T14:44:55Z
dlang/dmd pull request #16315 "Fix Bugzilla 24434 - Casting away const with cast() is not a @safe lv…" was merged into master:
- c2eac7ce389eb174cfbb96e66ab4fddb1b48a4b2 by Nick Treleaven:
Workaround for safe append
Fixes Bugzilla 23530 - casting immutable away allowed in safe.
https://github.com/dlang/dmd/pull/16315