Avoiding the Null Trap in Privilege Mode Drivers
TL;DR: Using null pointers in critical code can crash your system
-
Memory access violation
-
Unpredictable behavior
-
Null Pointer Dereference
-
Unexpected program termination
-
System instability
-
No healing/recovery strategy
-
Security Risk
-
Avoid using NULLs
-
Make controlled releases to mission-critical software
-
Create better rollback strategies instead of BSOD
-
Use Smart Pointers: Manage memory automatically and avoid null pointers with smart pointers
-
Create self-healing software.
-
Apply defensive programming
-
Improve your QA tests before deploying to production.
When you use nulls in a privileged driver, you risk causing serious issues.
Privilege mode drivers run with high permissions, and if you use a null pointer, the system might try to access an invalid memory address.
For example, trying to read from address 0x9c (156) or using 0x0 as a special value can lead to critical errors.
You can't just abort the program in privileged mode, so you must handle these cases carefully.
In privileged drivers, null pointer usage poses significant risks. You can mitigate these risks using modern C++ features like std::optional.
This problem caused one of the worst software blackouts in 2024.
// This case is not exactly what happened with Crowdstrike
// It is here for illustration purposes
void* get_data() {
if (data_available) {
return data_ptr; // This could be null!
} else {
// Uh oh, what if data_ptr is null here?
return NULL;
// Using Null to indicate no data
// knowing Null is schizophrenic
}
}
int process_data(void* data) {
if (data != NULL) {
// Maybe a null check, but not guaranteed!
// Accessing data... (crash if data is Null)
return *data;
}
// No check? Silent failure or unexpected behavior.
return -1;
}
// You should ideally replace the null with a polymorphic call
// You can see the technique in related articles
std::unique_ptr<int> get_data() {
if (data_available) {
return std::make_unique<int>(data_value);
} else {
return nullptr; // Explicitly return nullptr
}
}
int process_data(const std::unique_ptr<int>& data) {
if (data) { // Check for valid pointer
return *data;
} else {
// Handle no data case (e.g., return default value)
return 0;
}
}
[X] Semi-Automatic
You can detect this smell by checking for null pointer usage in critical parts of your code. Look for functions that process pointers and see if they handle null pointers safely.
Human code reviews are good for checking this kind of problem.
- Null
[x] Advanced
AI generators can sometimes produce this smell, especially if they generate code without context about the environment where the code will run.
AI generators are fed with code with NULL usage even though his creator told us to avoid it altogether.
AI tools can detect this smell with specific instructions.
AI can be trained to identify code patterns.
Teaching it the nuances of privileged driver development and null safety best practices might require more advanced techniques.
Use static analysis tools to flag null pointer dereferences.
Voyager 1's software has been running for more than 50 years.
It was designed to be robust, reliable, and redundant which is sadly uncommon in some immature systems in 2024.
Avoid using null pointers in privileged mode drivers.
I have written a book on clean code and a whole chapter #15 on how to avoid NULL and all the consequences it carries.
Hopefully, Crowdstrike engineers will read it!
Code Smell 126 - Fake Null Object
Null: The Billion Dollar Mistake
%[https://github.com/google/sanitizers/wiki/AddressSanitizer]
Code Smells are my opinion.
I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
Tony Hoare
Software Engineering Great Quotes
This article is part of the CodeSmell Series.