June 27, 2017 [Issue 17561] New: @safe code can write beyond Fiber's stack, despite guard page | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=17561 Issue ID: 17561 Summary: @safe code can write beyond Fiber's stack, despite guard page Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Keywords: safe Severity: normal Priority: P1 Component: dmd Assignee: nobody@puremagic.com Reporter: ag0aep6g@gmail.com 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. -- |
Copyright © 1999-2021 by the D Language Foundation