[Not really OT] Crowdstrike Analysis: It was a NULL pointer from the memory unsafe C++ language.
Richard (Rikki) Andrew Cattermole
richard at cattermole.co.nz
Sat Jul 27 19:00:46 UTC 2024
On 28/07/2024 6:33 AM, Walter Bright wrote:
> On 7/27/2024 2:30 AM, Richard (Rikki) Andrew Cattermole wrote:
>> There are two solutions for a native language that isn't just ignoring
>> it like we do today. Check it at CT and warn/error if you do not
>> handle null, or inject read barriers like we do for bounds checks to
>> cause the runtime exception.
>
> How is `assert(p != null)` better?
Two reasons.
1. You made the decision. You had to consider what would happen in this
situation. The question was asked, what happens should this be null? If
you want to assert that's fine. What is not fine is making an assumption
and never state it, never have it proven to be true.
2. It throws an exception (in D), which can be caught safely. It is only
when exception chaining occurs that the state may not have been cleaned
up correctly.
An even better solution to using an assert, is to use an if statement
instead.
```d
if (int* ptr = var.field) {
// success
} else {
// fail, you can gracefully degrade/log here
}
```
With the help of ``?.`` operator, we can also make this very nice to use
for loads and stores, AND be temporally safe!
```d
if (S1* ptr1 = var.field1) {
if (S2* ptr2 = ptr1.field2) {
// success
goto AfterFailure;
}
}
// failure
AfterFailure:
```
From:
```d
if (int* ptr = var?.field1?.field2) {
// success
} else {
// failure
}
```
>> Note: this is solved in C/C++ world. They have such analysis in their
>> compilers: analyzer-null-dereference
>>
>> https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/Static-Analyzer-Options.html
>
> -Wanalyzer-possible-null-argument
>
> That's not solving it.
Yes and no.
It cannot solve it completely in C or C++ because there is no language
integration.
For temporal safety, you have to make sure you do a load into a
variable, and only then do the test.
Which means this:
```d
void func(int** ptr) {
assert(*ptr !is null);
int i = **ptr; // ERROR: `**ptr` is in an unknown type state, it could
be null
}
```
> Many simple cases can indeed be found by DFA. But not all. There's also
> a lot of DFA trying to eliminate array bounds errors, but such errors
> remain the #1 security problem with C and C++.
>
> D does insert checks for array bounds overflow, because the hardware is
> of no help.
I agree about bounds checks. However as read barriers, these are things
that we do control, and throw an exception that we can catch.
For this reason, bounds checks do not need CT analysis. They do not have
to bring down an application if caught.
On the other hand, null dereference requires signal handling to catch.
If you don't own thread and process you cannot use that to throw an
exception. For this reason it's not comparable and requires CT analysis
to prevent bringing down the process.
On the other hand, if you were to propose read barriers that throw
exceptions for null dereference, I would agree to the statement that
they are comparable.
>> It only takes one major outage where a business loses money before
>> they consider dumping a D companies solution. No client wants to hear:
>> "We did this in a known unsafe language for this particular error,
>> when a more main stream language has solutions to it and D doesn't."
>
> How is this different from `assert(p != null)` ?
See at top of my reply.
A joke I've been making at BeerConf atm (more or less):
User: Press F5
User: Press F5
User: Press F5, WHY ISN'T THE ABOUT PAGE SHOWING??????
User: Press F5 * 1000
Developer: Why are all the web server instances down?
Developer: Oh a segfault due to null dereference
User: Press F5 * 100000000000
Owner: Why did you use D! If you just used <insert mainstream
application VM language> we wouldn't have lost millions of dollars!!!
More information about the Digitalmars-d
mailing list