[Issue 24696] New: Lack of null reference checking enables full access to arbitrary memory locations in @safe

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Aug 5 21:08:26 UTC 2024


https://issues.dlang.org/show_bug.cgi?id=24696

          Issue ID: 24696
           Summary: Lack of null reference checking enables full access to
                    arbitrary memory locations in @safe
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Keywords: safe
          Severity: critical
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: elpenguino+D at gmail.com

Consider the following program, compiled with -m32:
```
struct RawMemoryAccess {
        private enum limit = 16 * 1024 * 1024;
        static foreach (i; 0 .. 255) {
                mixin("ubyte[limit] array", i, ";");
        }
        ref ubyte opIndex(size_t index) @safe return {
                switch (index >> 24) {
                        static foreach (i; 0 .. 255) {
                                case i: return this.tupleof[i][index % limit];
                        }
                        default: assert(0);
                }
        }
}
void main() @safe {
        RawMemoryAccess* f;
        int* i = new int(4);
        (*f)[cast(size_t)i] = 42; // muahahaha
        assert(*i == 4);
}
```
Thanks to relying completely on hardware for null-reference checking, we can
get away with completely memory-safe arbitrary memory access with a simple
struct the same size of the entire memory space. Limiting static arrays to 16MB
makes it trickier, but still quite trivial to bypass.

Although this example only functions with -m32, it can be adapted to 64-bit
builds as well, though it would require either pushing CTFE well beyond its
current limits or the submission of a 36TB+ .d module, neither of which are
reasonable.

--


More information about the Digitalmars-d-bugs mailing list