Prototype of Ownership/Borrowing System for D

mipri mipri at minimaltype.com
Sun Nov 24 04:05:41 UTC 2019


On Sunday, 24 November 2019 at 03:42:00 UTC, Jab wrote:
> You can have use-after-free bugs happen in @live code, as a 
> result of what is passed into @live functions.
>
>
> void zoo() {
>     int* p = cast(int*)malloc( int.sizeof * 2 );
>     foo(p, p + 1);
> }
>
> @live void foo( int* p, int* q ) {
>     free(p);
>
>     *q = 10; // use after free.
> }

And this crashes dmd:
---
import core.stdc.stdlib: malloc, free;

@live void zoo() {
     int* p = cast(int*)malloc( int.sizeof * 2 );
     foo(p, p + 1);
}

@live void foo( scope int* p, scope int* q ) {
     *q = 10; // use after free.
}
---
core.exception.RangeError at dmd/ob.d(1526): Range violation

It's zoo's @live that does it.

> The very error that @live is supposed to stop happens inside of 
> the function on it's watch. Sure you can pass a garbage pointer 
> to @safe, but the garbage pointer is created in code that isn't 
> marked safe. Here it happens inside of @live itself.

The user-after-free occurs there but the caller is still
violating foo()'s signature by saying "here are two pointers
that you are now the owner of" when it impossible for foo()
to dispose of them safely.

OTOH, I guess it's always the case that @live code can't
safely take ownership of an unknown pointer, because it can't
distinguish between a pointer the GC will clean up vs. a
pointer that a third party allocator must clean up vs. a
pointer to statically allocated memory that doesn't bear
cleaning up.



More information about the Digitalmars-d mailing list