Fantastic exchange from DConf
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Fri May 19 08:12:20 PDT 2017
On 5/19/17 9:46 AM, Moritz Maxeiner wrote:
> On Friday, 19 May 2017 at 11:53:57 UTC, Steven Schveighoffer wrote:
>> This provides a foundation to build completely @safe libraries.
>
> Agreed if you mean libraries being marked completely as @safe (which I
> assume).
> Disagreed if you mean libraries that are proven to never corrupt memory
> (not possible with unsafe operating system).
I mean libraries which only contain @safe and @system calls.
i.e.:
$ grep -R '@trusted' libsafe | wc -l
0
>> 2. @trusted blocks in any project need to be considered red flags. You
>> should not need to audit @safe code.
>
> Yes you do, because it can call into @trusted like this:
>
> ---
> void foo(int[] bar) @safe
> {
> () @trusted {
> // Exploitable code here
> }();
> }
> ---
>
> You *must* audit third party @safe code for such hidden @trusted code
> (e.g. grep recursively through such third party code for @trusted and
> verify).
This is what I mean by auditing @trusted when it interacts with @safe code.
Using your example, if we confirm that no matter how you call foo, the
@trusted block cannot break memory safety, then foo becomes a verified
@safe function. Then any @safe function that calls foo can be considered
@safe without auditing.
This is actually a necessity, because templates can infer safety, so you
may not even know the call needs to be audited. The most dangerous thing
I think is to have @trusted blocks which use templated types.
A real example recently was a PR that added @safe to a function, and
made the following call:
() @trusted { return CreateDirectoryW(pathname.tempCStringW(), null); }
Where pathname was a range. The trusted block is to allow the call to
CreateDirectoryW, but inadvertently, you are trusting all the range
functions inside pathname, whatever that type is!
The correct solution is:
auto cstr = pathname.tempCStringW();
() @trusted { return CreateDirectoryW(cstr, null); }
So yes, if the third party has @trusted code, you need to audit it. But
once you have audited the *block* of trusted code, and how it interacts
within its function, you can consider the calling @safe functions
actually safe without auditing.
>> If we get into "@safe really means @trusted" territory, we have lost.
>
> For code that you write yourself, @safe means @safe, of course. For code
> other people write and you want to call, it being marked @safe does
> really mean @trusted as long as you yourself have not looked inside it
> and verified there either is no hidden @trusted, or verified *yourself*
> that the hidden @trusted is memory safe.
> I consider any other behaviour to be negligent to the degree of "you
> don't actually care about memory safety at all".
I think there will be a good market for separating libraries between
@trusted-containing libraries, and only @safe-containing libraries. This
will make the auditing more focused, and more shareable. I don't expect
people to use Phobos and audit all the @trusted blocks personally. If "D
is memory safe" means "D is memory safe ONLY if you verify all of the
standard library personally", we still have lost.
-Steve
More information about the Digitalmars-d
mailing list