all OS functions should be "nothrow @trusted @nogc"

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 27 07:45:03 PDT 2017


On 7/27/17 10:20 AM, Moritz Maxeiner wrote:
> On Thursday, 27 July 2017 at 13:56:00 UTC, Steven Schveighoffer wrote:
>> On 7/27/17 9:24 AM, Moritz Maxeiner wrote:
>>> On Wednesday, 26 July 2017 at 01:09:50 UTC, Steven Schveighoffer wrote:
>>>> I think we can correctly assume no fclose implementations exist that 
>>>> do anything but access data pointed at by stream. Which means a 
>>>> segfault on every platform we support.
>>>>
>>>> On platforms that may not segfault, you'd be on your own.
>>>>
>>>> In other words, I think we can assume for any C functions that are 
>>>> passed pointers that dereference those pointers, passing null is 
>>>> safely going to segfault.
>>>>
>>>> Likewise, because D depends on hardware flagging of dereferencing 
>>>> null as a segfault, any platforms that *don't* have that for C also 
>>>> won't have it for D. And then @safe doesn't even work in D code either.
>>>>
>>>> As we have good support for different prototypes for different 
>>>> platforms, we could potentially unmark those as @trusted in those 
>>>> cases.
>>>
>>> --- null.d ---
>>> version (linux):
>>>
>>> import core.stdc.stdio : FILE;
>>> import core.sys.linux.sys.mman;
>>>
>>> extern (C) @safe int fgetc(FILE* stream);
>>>
>>> void mmapNull()
>>> {
>>>      void* mmapNull = mmap(null, 4096, PROT_READ | PROT_WRITE, 
>>> MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE, -1, 0);
>>>      assert (mmapNull == null, "Do `echo 0 > 
>>> /proc/sys/vm/mmap_min_addr` as root");
>>>      *(cast (char*) null) = 'D';
>>> }
>>>
>>> void nullDeref() @safe
>>> {
>>>      fgetc(null);
>>> }
>>>
>>> void main(string[] args)
>>> {
>>>      mmapNull();
>>>      nullDeref();
>>> }
>>> ---
>>>
>>> For some fun on Linux, try out
>>> # echo 0 > /proc/sys/vm/mmap_min_addr
>>> $ rdmd null.d
>>>
>>> Consider `mmapNull` being run in some third party shared lib you 
>>> don't control.
>>
>> Again, all these hacks are just messing with the assumptions D is making.
> 
> Which aren't in the official D spec (or at the very least I can't seem 
> to find them there).

You are right. I have asked Walter to add such an update. I should pull 
that out to its own thread, will do.

>> You don't need C functions to trigger such problems.
> 
> Sure, but it was relevant to the previous discussion.

Right, but what I'm saying is that it's a different argument. We could 
say "you can't mark fgetc @safe", and still have this situation occur.

>> I'm fine with saying libraries or platforms that do not segfault when 
>> accessing zero page are incompatible with @safe code.
> 
> So we can't have @safe in shared libraries on Linux? Because there's no 
> way for the shared lib author to know what programs using it are going 
> to do.

You can't guarantee @safe on such processes or systems. It has to be 
assumed by the compiler that your provided code doesn't happen.

It's not that we can't have @safe because of what someone might do, it's 
that @safe guarantees can only work if you don't do such things.

It is nice to be aware of these possibilities, since they could be an 
effective attack on D @safe code.

>> And it's on you not to do this, the compiler will assume the segfault 
>> will occur.
> 
> It's not a promise the author of the D code can (always) make.
> In any case, the @trusted and @safe spec need to be explicit about the 
> assumptions made.

I agree. The promise only works as well as the environment. @safe is not 
actually safe if it's based on incorrect assumptions.

-Steve


More information about the Digitalmars-d mailing list