Thread overview
So these two compile and, in non-debug builds, run just fine
Nov 25, 2016
Ethan Watson
Nov 25, 2016
Ethan Watson
Nov 28, 2016
Walter Bright
Nov 25, 2016
Mathias Lang
Nov 28, 2016
Somebody
Nov 26, 2016
Era Scarecrow
November 25, 2016
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.
November 25, 2016
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
November 25, 2016
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.
November 26, 2016
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.


November 26, 2016
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.
November 28, 2016
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.

November 28, 2016
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.