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

Siarhei Siamashka siarhei.siamashka at gmail.com
Wed Dec 7 04:38:28 UTC 2022


On Tuesday, 6 December 2022 at 22:26:17 UTC, Sergey wrote:
> On Tuesday, 6 December 2022 at 04:35:18 UTC, Siarhei Siamashka 
> wrote:
>> end users. While D compilers don't offer any reasonable 
>> protection. Except for GDC, which supports `-ftrapv` option as 
>> an undocumented "Easter egg".
>
> What about these modules?
> https://dlang.org/phobos/std_checkedint.html
> https://dlang.org/phobos/core_checkedint.html

Imagine that you have several millions of D code (a big popular 
browser) and you want to do something to safeguard against 
integer overflow bugs and security issues (or at least mitigate 
them). How would these modules help?

In my opinion, the `std.checkedint` module is completely useless 
and there are no practical scenarios in the real world where it 
can help in any meaningful way. I see no real alternative to 
`-ftrapv` or UBSan for integer overflows diagnostics in large 
software projects. But the `core.checkedint` module is surely 
useful *after* you already know the exact part of the code where 
the overflow happens and needs to be patched up.

My reply would be incomplete without mentioning that D compilers 
do have some limited static analysis at compile time, intended to 
improve integer overflows safety: 
https://dlang.org/spec/type.html#vrp
But this analysis doesn't catch everything and it also sometimes 
unnecessarily gets in the way by forcing type casts. So it's not 
good enough. Want to see it in action? Here's one example:

```D
import std.stdio;
void main() {
   long bigsum = 0;
   int min_a = int.max - 50, max_a = int.max - 1;
   int min_b = 50, max_b = 100;
   foreach (a ; min_a .. max_a + 1) {
     foreach (b ; min_b .. max_b + 1) {
       // Compiles fine, but overflows at runtime
       int a_plus_b = a + b;
       bigsum += a_plus_b;
     }
   }
   byte min_c = 1, max_c = 50;
   byte min_d = 1, max_d = 50;
   foreach (c ; min_c .. max_c + 1) {
     foreach (d ; min_d .. max_d + 1) {
       // Won't compile without this explicit cast
       byte c_plus_d = cast(byte)(c + d);
       bigsum += c_plus_d;
     }
   }
   writeln(bigsum);
}
```

```
$ gdc -ftrapv test.d && ./a.out
Aborted

$ gdc test.d && ./a.out
-5471788083929
```


More information about the Digitalmars-d mailing list