@trusted assumptions about @safe code

ag0aep6g anonymous at example.com
Tue May 26 22:52:09 UTC 2020


On 26.05.20 17:41, Steven Schveighoffer wrote:
> The main problem is that f does not provide a safe value to g. @safe 
> code can always mess up if handed garbage. One might say that f should 
> not be @trusted. But that just means NO functions could be trusted. If 
> you cannot trust the semantic expectations of the functions you are 
> calling to hold true, then you cannot write @trusted code ever. I mean, 
> someone could do this inside memcpy:
> 
> size_t memcpy(void *dst, void *src, size_t length)
> {
>     *(size_t *)(dst + length + 10) = 0xdeadbeef;
>     ...// normal implementation
> }
> 
> And violate safety that way. So does that mean you can never use memcpy 
> inside @trusted functions *just in case* it did something like this?
> 
> I get what you are saying, that it would be nice if one can just write 
> @safe code and never worry that you might violate any memory rules. But 
> in reality, you still have to implement the function as designed, and 
> unless you do that, you are not going to be memory safe, period. The 
> only call stacks that would be "safe" were ones that were @safe all the 
> way down. And then @safe becomes essentially useless.

I think you've got a good point, but the example isn't so great. memcpy 
is @system and can only be @system, so of course you can break safety by 
changing its behavior.

But yeah, the @trusted function might rely on the @safe function 
returning 42. And when it suddenly returns 43, all hell breaks loose. 
There doesn't need to be any monkey business with unsafe aliasing or 
such. Just an @safe function returning an unexpected value.

I suppose the only ways to catch that kind of thing would be to forbid 
calling @safe (and other @trusted?) functions from @trusted (and 
@system?) code, or to mandate that the exact behavior of @safe functions 
(including their return values) cannot be relied upon for safety. Those 
would be really, really tough sells.

So unless we do something very drastic, any visible change in the 
behavior of an @safe function can possibly lead to memory corruption. 
And strictly speaking, any @trusted and @system code that calls it must 
be re-evaluated for safety.

Seems kinda obvious now. But I don't think I really realized this before.


More information about the Digitalmars-d mailing list