CPP: Add test cases for ConditionallyUninitializedVariables.ql.

This commit is contained in:
Geoffrey White
2019-10-28 18:43:00 +00:00
parent d693eb8c20
commit c40c88ec4b
4 changed files with 143 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
| examples.cpp:38:3:38:18 | call to initDeviceConfig | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | examples.cpp:13:5:13:20 | initDeviceConfig | initDeviceConfig | examples.cpp:37:16:37:21 | config | config |
| test.cpp:22:2:22:17 | call to maybeInitialize1 | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | test.cpp:4:5:4:20 | maybeInitialize1 | maybeInitialize1 | test.cpp:19:6:19:6 | a | a |
| test.cpp:68:2:68:17 | call to maybeInitialize2 | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | test.cpp:51:6:51:21 | maybeInitialize2 | maybeInitialize2 | test.cpp:66:6:66:6 | a | a |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql

View File

@@ -0,0 +1,43 @@
// based on the qhelp
int getMaxDevices();
bool fetchIsDeviceEnabled(int deviceNumber);
int fetchDeviceChannel(int deviceNumber);
void notifyChannel(int channel);
struct DeviceConfig {
bool isEnabled;
int channel;
};
int initDeviceConfig(DeviceConfig *ref, int deviceNumber) {
if (deviceNumber >= getMaxDevices()) {
// No device with that number, return -1 to indicate failure
return -1;
}
// Device with that number, fetch parameters and initialize struct
ref->isEnabled = fetchIsDeviceEnabled(deviceNumber);
ref->channel = fetchDeviceChannel(deviceNumber);
// Return 0 to indicate success
return 0;
}
void notifyGood(int deviceNumber) {
DeviceConfig config;
int statusCode = initDeviceConfig(&config, deviceNumber);
if (statusCode == 0) {
// GOOD: Status code returned by initialization function is checked, so this is safe
if (config.isEnabled) {
notifyChannel(config.channel);
}
}
}
int notifyBad(int deviceNumber) {
DeviceConfig config;
initDeviceConfig(&config, deviceNumber);
// BAD: Using config without checking the status code that is returned
if (config.isEnabled) {
notifyChannel(config.channel);
}
}

View File

@@ -0,0 +1,96 @@
void use(int i);
int maybeInitialize1(int *v)
{
static int resources = 100;
if (resources == 0)
{
return 0; // FAIL
}
*v = resources--;
return 1; // SUCCESS
}
void test1()
{
int a, b, c, d, e, f;
int result1, result2;
maybeInitialize1(&a); // BAD (initialization not checked)
use(a);
if (maybeInitialize1(&b) == 1) // GOOD
{
use(b);
}
if (maybeInitialize1(&c) == 0) // BAD (initialization check is wrong) [NOT DETECTED]
{
use(c);
}
result1 = maybeInitialize1(&d); // BAD (initialization stored but not checked) [NOT DETECTED]
use(d);
result2 = maybeInitialize1(&e); // GOOD
if (result2 == 1)
{
use(e);
}
if (maybeInitialize1(&f) == 0) // GOOD
{
return;
}
use(f);
}
bool maybeInitialize2(int *v)
{
static int resources = 100;
if (resources > 0)
{
*v = resources--;
return true; // SUCCESS
}
return false; // FAIL
}
void test2()
{
int a, b;
maybeInitialize2(&a); // BAD (initialization not checked)
use(a);
if (maybeInitialize2(&b)) // GOOD
{
use(b);
}
}
int alwaysInitialize(int *v)
{
static int resources = 0;
*v = resources++;
return 1; // SUCCESS
}
void test3()
{
int a, b;
alwaysInitialize(&a); // GOOD (initialization never fails)
use(a);
if (alwaysInitialize(&b) == 1) // GOOD
{
use(b);
}
}