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

Reply via email to