Typical security issues in C++: why the GC isn't your enemy

Siarhei Siamashka siarhei.siamashka at gmail.com
Wed Dec 14 22:44:38 UTC 2022


On Wednesday, 14 December 2022 at 20:54:44 UTC, 
areYouSureAboutThat wrote:
> On Wednesday, 14 December 2022 at 11:45:02 UTC, Dukc wrote:
>>
>> This is really just a nice shorthand for the `@safe` main with 
>> `@trusted` lambda inside. It's also a better practice, since 
>> `@trusted` in a function signature is easier to spot for a 
>> code reviewer than the lambda inside the function.
>
> The point of my referencing that link, is that you cannot 
> compile in unsafe code into your library in Rust without (1) 
> the compiler telling you, you can't do it unless.. or (2) you 
> do what the compiler tells you.
>
> That is, you cannot unknowingly compile in unsafe code into 
> your library.

Dukc already explained it, but let me show some practical 
examples. Here's a buggy program in Rust:

```Rust
use std::slice;

unsafe fn f(i: usize) -> i32 {
     let mut arr = [1, 2, 3];
     let s = slice::from_raw_parts_mut(arr.as_mut_ptr(), 1000);
     return s[i];
}

fn main() {
     unsafe { println!("{}", f(3)); } // ok!
}
```

And here's exactly the same buggy program converted to D:

```D
@safe: import std;

@system int f(size_t i) {
     auto arr = [1, 2, 3];
     return arr.ptr[i];
}

void main() {
     () @trusted { writeln(f(3)); }(); // ok!
}
```

Both Rust and D compilers accept this code without complaining. 
Such code can be unknowingly compiled into your library. It may 
be a part of the standard library, or it may be a part of some 
third-party library that you want to use. And if the bug is 
difficult to reproduce, then you even won't be aware of it.

Now if you review the code, then D code is much more readable 
than Rust. If you want to find the boundary between safe and 
unsafe code in D, then you can just search for the "@trusted" 
attribute. But in Rust you can't easily find the boundary between 
safe and unsafe code, because the same "unsafe" keyword is reused 
for different purposes.

> @trusted is no different from @system

It's is very different. If you look at a function as a black box 
without knowing what is inside, then:

   * `@trusted` function is typically safe to use. But this safety 
is guaranteed by human reviewers, because the compiler is not 
smart enough to do such analysis. It's important that the way how 
such functions are handling their input/output data is reasonably 
foolproof.

   * `@system` function may have some dangerous quirks and can be 
easily misused to shoot yourself in the foot (leak resources, 
segfault on incorrect input, deadlock when used from multiple 
threads, ...). It can be used correctly if the user is very 
careful, but allowing to call such function directly from the 
`@safe` code would be reckless.


More information about the Digitalmars-d mailing list