Issue 24696 - Lack of null reference checking enables full access to arbitrary memory locations in @safe
Summary: Lack of null reference checking enables full access to arbitrary memory locat...
Status: RESOLVED DUPLICATE of issue 5176
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 critical
Assignee: No Owner
URL:
Keywords: safe
Depends on:
Blocks:
 
Reported: 2024-08-05 21:08 UTC by elpenguino+D
Modified: 2024-08-06 12:07 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description elpenguino+D 2024-08-05 21:08:26 UTC
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.
Comment 1 RazvanN 2024-08-06 12:07:37 UTC
This is a known issue reported a long time ago: https://issues.dlang.org/show_bug.cgi?id=5176

*** This issue has been marked as a duplicate of issue 5176 ***