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