www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5176] New: Limit static object sizes

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176

           Summary: Limit static object sizes
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: Mac OS X
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: andrei metalanguage.com


--- Comment #0 from Andrei Alexandrescu <andrei metalanguage.com> 2010-11-05
17:38:13 PDT ---
Objects of very large size can corrupt memory when used via null pointers:

struct S {
    char raw[100_000];
}

S * s = null;

To avoid this, static object sizes should be limited to a value that guarantees
hardware memory protection (e.g. 64KB).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 05 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc


--- Comment #1 from bearophile_hugs eml.cc 2010-11-06 00:46:12 PDT ---
Is this for  safe modules only?
If the answer is negative, what's the way to override this limit? If I am
writing a kernel using D, that's a system language, I may want to ignore this
corruption problem.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


nfxjfg gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nfxjfg gmail.com


--- Comment #2 from nfxjfg gmail.com 2010-11-06 02:46:38 PDT ---
64 KB ought to be enough for everyone.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #3 from Andrei Alexandrescu <andrei metalanguage.com> 2010-11-06
06:43:55 PDT ---
This change doesn't limit what can be done in a systems-level program.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |michel.fortin michelf.com


--- Comment #4 from yebblies <yebblies gmail.com> 2011-06-16 01:04:46 PDT ---
*** Issue 3677 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 16 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #5 from Michel Fortin <michel.fortin michelf.com> 2011-06-16
06:23:20 EDT ---
(In reply to comment #0)
 To avoid this, static object sizes should be limited to a value that guarantees
 hardware memory protection (e.g. 64KB).
I think on OS X the size of that guaranty is significantly smaller, 4 Kb if I remember well. Is it reasonable to limit structs and objects to 4 Kb on OS X? Note that it's not only structs and objects. Types such as char[100_000]* also pose a risk. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 16 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #6 from Andrei Alexandrescu <andrei metalanguage.com> 2012-03-18
10:03:05 PDT ---
One possibility is to allow arbitrary sizes but have the compiler insert checks
for all field accesses through pointer or reference when the field offset is
beyond the OS's protected area.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 18 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


klickverbot <code klickverbot.at> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code klickverbot.at


--- Comment #7 from klickverbot <code klickverbot.at> 2012-03-18 10:07:28 PDT
---
In reply to comment #5)
 I think on OS X the size of that guaranty is significantly smaller, 4 Kb if I
 remember well. Is it reasonable to limit structs and objects to 4 Kb on OS X?
Wouldn't it also be possible to additionally protect memory up to the desired safe object size limit during application startup? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 18 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


deadalnix <deadalnix gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |deadalnix gmail.com


--- Comment #8 from deadalnix <deadalnix gmail.com> 2012-03-18 10:14:04 PDT ---
What about int[1000000]* ? The problem is the same.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 18 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #9 from Michel Fortin <michel.fortin michelf.com> 2012-03-20
07:14:52 EDT ---
(In reply to comment #7)
 Wouldn't it also be possible to additionally protect memory up to the desired
  safe object size limit during application startup?
That'll work only if those pages are not used for anything. My guess is that if they're readable (writable?) it's because they're being used in some way, possibly by some system APIs. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 20 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #10 from Michel Fortin <michel.fortin michelf.com> 2012-03-20
07:45:08 EDT ---
(In reply to comment #6)
 One possibility is to allow arbitrary sizes but have the compiler insert checks
 for all field accesses through pointer or reference when the field offset is
 beyond the OS's protected area.
That'd work. It'd introduce uneven performance characteristics, but that could be the price to pay for safety. (To not pay this price we'd need statically-enforced non-nullable pointers.) On second thought, it needs a little tweak. Take this example: struct A { /* a lot of fields */ int f; // offset is 3 Kb - 4 bytes } struct B { A a1; // field offset is 0 A a2; // field offset is 3 Kb } int foo(ref A a) { return a.f; // offset is 3K-4, considered safe? } int bar(B * b) { return foo(b.a2); // offset is 3K, considered safe? } Here, if you call bar(null), it'll call foo() with address null + 3K. foo() will in turn add 3K-4 to the pointer, making it 6K-4 bytes, beyond the 4K protected range. What you need to take into account when deciding to insert the null check is not whether the offset is beyond the protected range, but whether the memory area of the field is entirely encompassed in the protected range. So you need to use field.offsetof+field.sizeof < 4K (or whatever the protected range is for a specific machine). Note that you also need to do this same check when taking the address of a field: B * baz() { return null; } void coz() { B * b = baz(); A * a = &b.a2; // b.a2 spans on 3K..6K range, unsafe int f = a.f; // address of field is 6K-4 } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 20 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #11 from deadalnix <deadalnix gmail.com> 2012-03-20 04:50:47 PDT ---
(In reply to comment #10)
 (In reply to comment #6)
 One possibility is to allow arbitrary sizes but have the compiler insert checks
 for all field accesses through pointer or reference when the field offset is
 beyond the OS's protected area.
That'd work. It'd introduce uneven performance characteristics, but that could be the price to pay for safety. (To not pay this price we'd need statically-enforced non-nullable pointers.) On second thought, it needs a little tweak. Take this example: struct A { /* a lot of fields */ int f; // offset is 3 Kb - 4 bytes } struct B { A a1; // field offset is 0 A a2; // field offset is 3 Kb }
Classes are references types. So both a1.f and a2.f will have the same offset. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 20 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


hsteoh quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh quickfur.ath.cx


--- Comment #13 from hsteoh quickfur.ath.cx 2013-01-09 17:21:29 PST ---
Very large structs can also corrupt memory not just via null references, but
via stack overflow. (Just pass a large struct by value down a few levels of
recursion, and the stack will overflow.) And it's easier than one might think:

struct S {
  dchar[256] buffer;
}

Looks small, right? Well, sizeof(dchar)=4, which means sizeof(S)=1024. On
Linux, the default stacksize is about 4KB. That means passing S by value down
just 3-4 levels of recursion is enough to overflow the stack. And currently, I
don't think DMD does any handling for stack overflow; it just crashes (and may
corrupt memory as well, I didn't look into it).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #14 from deadalnix <deadalnix gmail.com> 2013-01-09 17:41:47 PST ---
(In reply to comment #13)
 Very large structs can also corrupt memory not just via null references, but
 via stack overflow. (Just pass a large struct by value down a few levels of
 recursion, and the stack will overflow.) And it's easier than one might think:
 
 struct S {
   dchar[256] buffer;
 }
 
 Looks small, right? Well, sizeof(dchar)=4, which means sizeof(S)=1024. On
 Linux, the default stacksize is about 4KB. That means passing S by value down
 just 3-4 levels of recursion is enough to overflow the stack. And currently, I
 don't think DMD does any handling for stack overflow; it just crashes (and may
 corrupt memory as well, I didn't look into it).
A page is reserved after the stack to detect it I think. It require to limit the size of what can be put on stack in a single operation. Or to add the checks that matter. But a better option IMO is to reserve an insane amount of memory space for fiber's stack (and then some page to be protected for stack overflow detection) and run everything within a fiber. This is not very 32 bits compliant, but can work really well on 64bits systems. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #15 from bearophile_hugs eml.cc 2013-01-09 18:30:05 PST ---
(In reply to comment #13)
 Very large structs can also corrupt memory not just via null references, but
 via stack overflow. (Just pass a large struct by value down a few levels of
 recursion, and the stack will overflow.) And it's easier than one might think:
 
 struct S {
   dchar[256] buffer;
 }
 
 Looks small, right? Well, sizeof(dchar)=4, which means sizeof(S)=1024. On
 Linux, the default stacksize is about 4KB. That means passing S by value down
 just 3-4 levels of recursion is enough to overflow the stack.
A 1 kb struct should be considered very little for the stack. Generally it's a good idea to use the stack in D, because it avoids many slow heap allocations and decreases pressure on the GC. On a modern PC with 1 GB RAM a D programmer should be free to use 1-10 MB of RAM for the stack. On Windows there is a linker command to increase the stack size.
 And currently, I
 don't think DMD does any handling for stack overflow; it just crashes (and may
 corrupt memory as well, I didn't look into it).
DMD used to give a readable error message on Windows, but now programs just crash. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #16 from bearophile_hugs eml.cc 2013-01-09 18:37:19 PST ---
(In reply to comment #14)

 Or to add the checks that matter.
Adding checks in non-release mode is a good idea. See also Issue 9242 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com


--- Comment #17 from Walter Bright <bugzilla digitalmars.com> 2013-01-09
21:24:23 PST ---
Windows inserts a "guard page" that is hardware protected beyond the end of the
allocated stack. A stack overflow runs into that guard page, which throws a seg
fault.

It does not corrupt memory.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


Jacob Carlborg <doob me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |doob me.com


--- Comment #18 from Jacob Carlborg <doob me.com> 2013-01-09 23:22:14 PST ---
(In reply to comment #17)
 Windows inserts a "guard page" that is hardware protected beyond the end of the
 allocated stack. A stack overflow runs into that guard page, which throws a seg
 fault.
 
 It does not corrupt memory.
What about the rest of the platforms? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #19 from Walter Bright <bugzilla digitalmars.com> 2013-01-09
23:52:41 PST ---
They all do it. It's a well-known technique (several decades) used when you've
got protected mode memory.

Of course, if you malloc your own stack, you don't have such protection.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Platform|Other                       |All
            Version|unspecified                 |D2
         OS/Version|Mac OS X                    |All
           Severity|normal                      |enhancement


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #20 from Don <clugdbug yahoo.com.au> 2013-01-10 01:14:30 PST ---
(In reply to comment #18)
 (In reply to comment #17)
 Windows inserts a "guard page" that is hardware protected beyond the end of the
 allocated stack. A stack overflow runs into that guard page, which throws a seg
 fault.
 
 It does not corrupt memory.
What about the rest of the platforms?
On our code (Linux only, derived from Tango, its basically the same as druntime) our fibers allocate a guard page at the end of the stack. We added this because we found that stack overflows in fibers are easy to create but difficult to debug. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #21 from bearophile_hugs eml.cc 2013-01-10 01:46:38 PST ---
(In reply to comment #17)
 Windows inserts a "guard page" that is hardware protected beyond the end of the
 allocated stack. A stack overflow runs into that guard page, which throws a seg
 fault.
 
 It does not corrupt memory.
So what's missing is just the stack trace. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #22 from Andrei Alexandrescu <andrei erdani.com> 2013-01-10
09:08:49 PST ---
How large are the guard pages on each OS?

We should either restrict object size to a reasonable maximum, or insert
runtime checks at least in  safe mode when accessing fields through pointers
that may be null.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #23 from Andrei Alexandrescu <andrei erdani.com> 2013-01-10
09:12:28 PST ---
Oh there's also a confusion. The problem is not with the stack, it's with
accessing fields through null pointers. Getting back to the original example:

struct S {
    char raw[100_000];
}

void main() {
  S * s = null;
  char a = raw[$ - 1];
}

That will issue an access through a pointer with a small value (100_000). The
question is what is the maximum small pointer that will cause a protection
fault on all OSs.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #24 from Jacob Carlborg <doob me.com> 2013-01-10 10:14:47 PST ---
(In reply to comment #22)
 How large are the guard pages on each OS?
 
 We should either restrict object size to a reasonable maximum, or insert
 runtime checks at least in  safe mode when accessing fields through pointers
 that may be null.
Perhaps doing something similar as with array bounds checking. Insert a check and provide a compiler flag to remove it. Or remove the check in -release builds. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #25 from hsteoh quickfur.ath.cx 2013-01-10 11:46:07 PST ---
(In reply to comment #17)
 Windows inserts a "guard page" that is hardware protected beyond the end of the
 allocated stack. A stack overflow runs into that guard page, which throws a seg
 fault.
 
 It does not corrupt memory.
Oh yes it does: http://d.puremagic.com/test-results/pull.ghtml?projectid=1&runid=448588 (But I did make a mistake, it's not Linux that this happens on, but OSX/64.) For reference, this is the failing code (N.B. the last assert, compare with output in the autotester, you can see that garbage values are produced, I've traced this and found that it's caused by stack overflow): unittest { struct TransientRange { dchar[128] _buf; dstring[] _values; this(dstring[] values) { _values = values; } property bool empty() { return _values.length == 0; } property auto front() { foreach (i; 0 .. _values.front.length) { _buf[i] = _values[0][i]; } return _buf[0 .. _values.front.length]; } void popFront() { _values = _values[1 .. $]; } } auto rr = TransientRange(["abc"d, "12"d, "def"d, "34"d]); // Can't use array() or equal() directly because they fail with transient // .front. dchar[] result; foreach (c; rr.joiner()) { result ~= c; } assert(equal(result, "abc12def34"d), "Unexpected result: '%s'"d.format(result)); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #26 from Walter Bright <bugzilla digitalmars.com> 2013-01-10
12:03:50 PST ---
(In reply to comment #22)
 How large are the guard pages on each OS?
Usually 4k. But the function prologs, when creating a stack frame larger than 4k, will do "probes" for each 4k page. So, no, you can't corrupt memory with an overflow.
 We should either restrict object size to a reasonable maximum, or insert
 runtime checks at least in  safe mode when accessing fields through pointers
 that may be null.
There's a separate set of guard pages at address 0, to cause a seg fault if 1, 2, 3, etc. is accessed. I don't know how big they are. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #27 from Walter Bright <bugzilla digitalmars.com> 2013-01-10
12:08:12 PST ---
 Oh yes it does:
You can test this with a far simpler program. Just write a function that calls itself and run it under the debugger. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176


9999 <sibaqexozequgaba tempomail.fr> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sibaqexozequgaba tempomail.
                   |                            |fr


--- Comment #28 from 9999 <sibaqexozequgaba tempomail.fr> 2013-05-20 00:58:57
PDT ---
Copying my comment from the forums so it won't get lost:
(http://forum.dlang.org/post/fuqkpmkfdjxwgmzfizuu forum.dlang.org)

Isn't the solution as easy as doing:
OR PTR:[address], 0
the same way it's done for the stack?

The offset it known at compile time in most cases, so the command 
would be required only if both:
* The object is larger than target OS' guard page size.
* The position is greater than target OS' guard page size, OR is 
unknown at compile time.

Walter: "Not a bad idea." :)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #29 from deadalnix <deadalnix gmail.com> 2013-05-20 01:07:53 PDT ---
(In reply to comment #28)
 Copying my comment from the forums so it won't get lost:
 (http://forum.dlang.org/post/fuqkpmkfdjxwgmzfizuu forum.dlang.org)
 
 Isn't the solution as easy as doing:
 OR PTR:[address], 0
 the same way it's done for the stack?
 
 The offset it known at compile time in most cases, so the command 
 would be required only if both:
 * The object is larger than target OS' guard page size.
 * The position is greater than target OS' guard page size, OR is 
 unknown at compile time.
 
 Walter: "Not a bad idea." :)
The thing is that you may get over the page protection by several dereferences. So you must check based not on the dereferenced address, but on the maximum addres that will be dereferenced (ie the end of the object). It means that every single reference taking on a 4kb+ object must have a check. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #30 from 9999 <sibaqexozequgaba tempomail.fr> 2013-05-20 01:13:22
PDT ---
(In reply to comment #29)
 The thing is that you may get over the page protection by several dereferences.
What do you mean by several dereferences? Can you provide an example? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #31 from deadalnix <deadalnix gmail.com> 2013-05-20 01:26:56 PDT ---
(In reply to comment #30)
 (In reply to comment #29)
 The thing is that you may get over the page protection by several dereferences.
What do you mean by several dereferences? Can you provide an example?
Yes sure. Let's consider the example below : struct Foo { ubyte[512] bar; } struct Buzz { ubyte[256] pad; Foo[8] qux; } Buzz* b; auto deref1 = (b.qux[7]); // deref below 4kb. deref1.bar[300]; // offset is bellow 4kb, but teh address is above 4kb. If we consider deref address only no check happens here. So it is needed to base the decision to check or not not based on the actual address, but according the the maximal address possibly reached. In other words, a 4kb+ conglomerate of value types need null check on every single pointer operation, even the on bellow 4kb. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #32 from 9999 <sibaqexozequgaba tempomail.fr> 2013-05-20 02:08:00
PDT ---
(In reply to comment #31)
 Yes sure. Let's consider the example below :
 
 struct Foo {
     ubyte[512] bar;
 }
 
 struct Buzz {
     ubyte[256] pad;
     Foo[8] qux;
 }
 
 Buzz* b;
 
 auto deref1 = (b.qux[7]); // deref below 4kb.
 deref1.bar[300]; // offset is bellow 4kb, but teh address is above 4kb.
 
 If we consider deref address only no check happens here. So it is needed to
 base the decision to check or not not based on the actual address, but
 according the the maximal address possibly reached.
 
 In other words, a 4kb+ conglomerate of value types need null check on every
 single pointer operation, even the on bellow 4kb.
Your example is safe, as it will crash on the first dereference (value semantics). You probably meant something similar to: Buzz* b; auto deref1 = &(b.qux[7]); // take address below 4kb. deref1.bar[300] = 0; // offset is bellow 4kb, but the address is above 4kb. Maybe it's worth adding another case then, when both are true: * Taking an address of an object whose size is above OS' guard page (Buzz in the example). * The referenced object's last available byte offset is above OS' guard page (qux[7]'s last byte in the example). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #33 from Andrei Alexandrescu <andrei erdani.com> 2013-05-20
05:34:03 PDT ---
(In reply to comment #32)
 Buzz* b;
 
 auto deref1 = &(b.qux[7]); // take address below 4kb.
 deref1.bar[300] = 0; // offset is bellow 4kb, but the address is above 4kb.
This is a red herring. The null check is inserted not if the address of the field falls above the limit, but if the address of the field PLUS the size of the field does. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #34 from 9999 <sibaqexozequgaba tempomail.fr> 2013-05-20 06:03:10
PDT ---
(In reply to comment #33)
 (In reply to comment #32)
 Buzz* b;
 
 auto deref1 = &(b.qux[7]); // take address below 4kb.
 deref1.bar[300] = 0; // offset is bellow 4kb, but the address is above 4kb.
This is a red herring. The null check is inserted not if the address of the field falls above the limit, but if the address of the field PLUS the size of the field does.
That's what I meant by saying "The referenced object's last available byte". -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 20 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5176



--- Comment #35 from Andrei Alexandrescu <andrei erdani.com> 2013-05-20
06:05:16 PDT ---
(In reply to comment #34)
 (In reply to comment #33)
 (In reply to comment #32)
 Buzz* b;
 
 auto deref1 = &(b.qux[7]); // take address below 4kb.
 deref1.bar[300] = 0; // offset is bellow 4kb, but the address is above 4kb.
This is a red herring. The null check is inserted not if the address of the field falls above the limit, but if the address of the field PLUS the size of the field does.
That's what I meant by saying "The referenced object's last available byte".
Thanks, I replied to the wrong message. But I don't think that's a special case, the check should always work that way. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 20 2013