Bug 17561 – @safe code can write beyond Fiber's stack, despite guard page

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2017-06-27T09:04:42Z
Last change time
2024-12-13T18:52:52Z
Keywords
safe
Assigned to
No Owner
Creator
ag0aep6g
See also
https://issues.dlang.org/show_bug.cgi?id=17566
Moved to GitHub: dmd#19269 →

Comments

Comment #0 by ag0aep6g — 2017-06-27T09:04:42Z
Inspired by <https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt> and <https://github.com/dlang/druntime/pull/1698>, here is some code that skips over a Fiber's stack guard page to corrupt another Fiber's stack: ---- import core.thread: Fiber; import std.conv: text; enum pagesize = 4096; /* educated guess */ enum distance = 5 * pagesize; /* 4 pages of stack + 1 guard page */ void main() { auto f1 = new Fiber(() @safe { ubyte[distance + 250] mess_up_f2 = void; /* skipping over the guard page */ mess_up_f2[0] = 13; }); auto f2 = new Fiber(() { ubyte[500] data = 0; foreach (d; data) assert(d == 0); /* passes */ Fiber.yield(); foreach (d; data) assert(d == 0, text(d)); /* fails; prints "13" */ }); assert(f1.tupleof[8] > f2.tupleof[8]); immutable actualDistance = f1.tupleof[8] - f2.tupleof[8]; assert(distance == actualDistance, text(actualDistance)); /* If this fails, change `distance` to printed value. */ f2.call(); /* f2 sets up its data */ f1.call(); /* f1 messes with it */ f2.call(); /* f2 sees the corrupted data */ } ---- Tested in Ubuntu Linux with a git HEAD dmd. Might behave differently on other platforms. As far as I see, this is an @safe issue, which can't be detected/prevented in the Fiber code. Fiber's operations are currently not @safe, but surely there is an expectation that a running an @safe function in a Fiber is safe. I guess one possible fix would be to outlaw void initialization in @safe code. Maybe it can be allowed below a certain size, when it's also ensured that guard pages have at least that size.
Comment #1 by ag0aep6g — 2017-06-27T09:07:27Z
(In reply to ag0aep6g from comment #0) > Tested [...] with a git HEAD dmd. Which is: DMD64 D Compiler v2.075.0-b1-37-gec11b11
Comment #2 by ag0aep6g — 2017-06-28T13:09:36Z
Same issue applies to the main stack. Filed separately: issue 17566.
Comment #3 by robert.schadek — 2024-12-13T18:52:52Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19269 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB