Avoiding the Null Trap in Privilege Mode Drivers
TL;DR: Using null pointers in critical code can crash your system
Problems
Memory access violation
Unpredictable behavior
Null Pointer Dereference
Unexpected program termination
System instability
No healing/recovery strategy
Security Risk
Solutions
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.
Context
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.
Sample Code
Wrong
// 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;
}
Right
// 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;
}
}
Detection
[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.
Tags
- Null
Level
[x] Advanced
AI Generation
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 Detection
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.
Conclusion
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!
Relations
More Info
Null: The Billion dollar mistake
Maxi Contieri ・ Nov 18 '20
This article is part of the CodeSmell Series.