www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - So these two compile and, in non-debug builds, run just fine

reply Ethan Watson <gooberman gmail.com> writes:
MyClass* getAPointer()
{
   MyClass* ptr;
   MyClass instance = new MyClass();
   ptr = &instance;
   return ptr;
}

MyStruct* getAnotherPointer()
{
   MyStruct* ptr;
   MyStruct instance;
   ptr = &instance;
   return ptr;
}

One of the guys here is working on some GC stuff (ARC related), 
and gave me a snippet of code that took a reference to a class on 
the stack, and assigned the address of it to another variable. 
Which meant that when the class reference goes out of scope, it's 
pointing to data on the stack that shouldn't be valid.

And you can break it in debug with a little bit of code as such:

MyClass* ptr = getAPointer();
MyStruct* someStruct = getAnotherPointer();
writeln( to!string( (*ptr).foo ) );

I wouldn't expect this to be something that can be detected at 
compile time. I mean, the code looks simple enough, but it's just 
the easiest way to show off the larger problem that returning by 
pointer is not validated. Ten minutes and you could write some 
horribly obfuscated code that still gives a return value that's a 
stack pointer.

I'm sure this sounds bad. And it is.

Related to this: 
https://msdn.microsoft.com/en-us/library/8dbf701c.aspx

The Windows App Certification Kit can pick up if the security 
token check isn't done on enter and exit of a function. And even 
if the codegen does the checks, stack pointers mean you can start 
doing stack overflows.
Nov 25 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/25/16 9:57 AM, Ethan Watson wrote:

 safe: // now it fails.
 MyClass* getAPointer()
 {
   MyClass* ptr;
   MyClass instance = new MyClass();
   ptr = &instance;
   return ptr;
 }

 MyStruct* getAnotherPointer()
 {
   MyStruct* ptr;
   MyStruct instance;
   ptr = &instance;
   return ptr;
 }
But I think Walter's scope changes (DIP 1001 I think?) will make it so the compiler rejects this even in non-safe mode. -Steve
Nov 25 2016
next sibling parent reply Ethan Watson <gooberman gmail.com> writes:
On Friday, 25 November 2016 at 15:30:35 UTC, Steven Schveighoffer 
wrote:
 But I think Walter's scope changes (DIP 1001 I think?) will 
 make it so the compiler rejects this even in non-safe mode.

 -Steve
I really hope this is the case. Because, it needs to be said. If a modern language fails something like this then it's really not good enough in a modern, security-focused environment.
Nov 25 2016
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/25/2016 2:51 PM, Ethan Watson wrote:
 On Friday, 25 November 2016 at 15:30:35 UTC, Steven Schveighoffer wrote:
 But I think Walter's scope changes (DIP 1001 I think?) will make it so the
 compiler rejects this even in non-safe mode.

 -Steve
I really hope this is the case. Because, it needs to be said. If a modern language fails something like this then it's really not good enough in a modern, security-focused environment.
I agree. That's the whole point of DIP1000. I predicted in my last presentation to NWCPP that it will soon be an industry requirement for selection of a programming language. Companies just cannot afford these sorts of bugs anymore.
Nov 28 2016
prev sibling next sibling parent reply Mathias Lang via Digitalmars-d <digitalmars-d puremagic.com> writes:
2016-11-25 16:30 GMT+01:00 Steven Schveighoffer via Digitalmars-d <
digitalmars-d puremagic.com>:

 But I think Walter's scope changes (DIP 1001 I think?) will make it so the
 compiler rejects this even in non-safe mode.

 -Steve
You are correct that DIP1000 will fix that. However it will only be enforced in safe mode, sadly. Ethan: If you slap a ` safe` on this function, they don't compile anymore.
Nov 25 2016
parent Somebody <ajieskola gmail.com> writes:
On Friday, 25 November 2016 at 23:04:44 UTC, Mathias Lang wrote:
 You are correct that DIP1000 will fix that. However it will 
 only be
 enforced in  safe mode, sadly.
I wonder why. If system code wanted to bypass it, it could cast the scoped ref into a traditional one. Wouldn't it be better if it emitted a warning without such cast? Not an error, for backwards compatibility.
Nov 28 2016
prev sibling parent Era Scarecrow <rtcvb32 yahoo.com> writes:
On Friday, 25 November 2016 at 15:30:35 UTC, Steven Schveighoffer 
wrote:
 But I think Walter's scope changes (DIP 1001 I think?) will 
 make it so the compiler rejects this even in non-safe mode.
Rejecting it would be nice... Although I wonder... I've been wondering and thinking about if we could add extra metadata to non-release code for the purpose of debugging. The idea being every variable will have an attached hidden metadata tag/field (let's assume 32bits). This can then flag the information in various ways. For memory allocation we have stack/GC/static/other, then we have if this was passed back from a function, was modified. Basic type information could specify what the general type origin was (when first allocated/first assigned), was a slice of large data, originally was const, or immutable, shared, a pointer that's been tampered with (say using bits for extra data vs an actual pointer), and anything else we wanted to potentially track. While this information isn't useful on the surface, hidden checks could be thrown out there, like returning a variable from the local stack when it might otherwise be obfuscated and hidden.
Nov 26 2016