Bug 15645 – Tuple.slice() causes memory corruption.

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2016-02-04T17:51:47Z
Last change time
2018-03-31T18:25:27Z
Assigned to
No Owner
Creator
Marco Leise

Comments

Comment #0 by Marco.Leise — 2016-02-04T17:51:47Z
Good thing we have @trusted to mark suspicious memory operations that are actually safe. When it covers a bug that @safe would have caught though, it leaves a bad taste... First let's look at the implementation: @property ref Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t to)() @trusted if (from <= to && to <= Types.length) { return *cast(typeof(return)*) &(field[from]); } To return a slice into the tuple, a pointer to the new first is reinterpreted as the new tuple type. This mirrors the effect of slicing an array, just that tuples are actually structs and that causes a serious problem. Consider we slice off the first element of the following tuple and compare the relative offsets of the 2nd and 3rd field respectively: pragma(msg, Tuple!(int, bool, string)._2.offsetof - Tuple!(int, bool, string)._1.offsetof); pragma(msg, Tuple!( bool, string)._1.offsetof - Tuple!( bool, string)._0.offsetof); This prints: 4LU 8LU So the relative offset of the string part moved which causes memory corruption when slice() reinterprets pointers. More visually the layout on amd64 is: 0 4 8 Tuple!(int, bool, string): int boolstring 0 4 8 Tuple!(bool, string): bool string The memory adresses of the boolean field match, but the string moves due to its alignment constraints.
Comment #1 by thomas.bockman — 2016-02-05T10:42:29Z
Proposed fix: https://github.com/D-Programming-Language/phobos/pull/3973 Please review it and let me know if you think this is a good approach.
Comment #2 by saurabh.das — 2016-02-05T12:27:40Z
Alternative fix: https://github.com/D-Programming-Language/phobos/pull/3975 This fixes the issue without changing the layout of the tuple. Please review and consider whether the changed function signature is okay. PS: This is my first pull request on Dlang, so do let me know if I've broken any guidelines/processes :)
Comment #3 by github-bugzilla — 2017-05-17T19:34:36Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/e63c620433f51da97a45e5400ca0a71202d7b129 issue 15645 - Prevent unsafe usage of Tuple.slice https://github.com/dlang/phobos/commit/a45dc664a94cdfa7931b55b111d03ecf9afb83fa Merge pull request #5342 from tsbockman/issue_15645 issue 15645 - Prevent unsafe usage of Tuple.slice merged-on-behalf-of: Jack Stouffer <[email protected]>
Comment #4 by github-bugzilla — 2017-06-17T11:34:36Z
Commits pushed to stable at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/e63c620433f51da97a45e5400ca0a71202d7b129 issue 15645 - Prevent unsafe usage of Tuple.slice https://github.com/dlang/phobos/commit/a45dc664a94cdfa7931b55b111d03ecf9afb83fa Merge pull request #5342 from tsbockman/issue_15645
Comment #5 by github-bugzilla — 2018-01-05T13:28:26Z
Commits pushed to dmd-cxx at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/e63c620433f51da97a45e5400ca0a71202d7b129 issue 15645 - Prevent unsafe usage of Tuple.slice https://github.com/dlang/phobos/commit/a45dc664a94cdfa7931b55b111d03ecf9afb83fa Merge pull request #5342 from tsbockman/issue_15645
Comment #6 by greensunny12 — 2018-03-31T18:25:27Z
This was fixed by https://github.com/dlang/phobos/pull/5342 (or well at least this PR prevents the unsafe usage).