SV.INCORRECT_RESOURCE_HANDLING.WRONG_STATUS
Insecure resource handling-status checking
Resource management issues can lead to over-consumption or exhaustion of resources. When a resource is allocated, it's important to release the resource properly and account for all potential exit paths. Similarly, the code needs to keep track of requests and releases, so that a resource isn't requested after it's been released or closed when it's already been released. This type of defect often occurs in function exits for exceptions or error handling.
The SV.INCORRECT_RESOURCE_HANDLING.WRONG_STATUS checker flags situations in which a resource is requested or released when its current status is incompatible for that action. For example, the resource code may be attempting to release the resource when it may have never been opened.
The checker analyzes the following POSIX resources for incorrect resource handling:
- Standard input/output resources: file descriptors, file, and pipe streams
- X/Open System Interface (XSI) resources: messages, semaphores, and shared memory
- Realtime resources: message queues, semaphores, shared memory, typed memory objects, process spawning, clocks, and timers
- Thread resources: threads, mutexes, conditional variables, barriers, read/write lock objects, and spin lock objects
- Sockets
- Traces
For more information, see the latest issue of The Open Group Base Specifications.
Vulnerability and risk
Although this situation isn't really a security risk, incorrect error handling can result in software reliability problems, and possibly in exposing sensitive data. If an attacker can intentionally trigger a resource leak, a resource pool could be reduced to the point of denial-of-service (DoS).
Mitigation and prevention
It's good practice to ensure that all resourced allocated are freed, and to be consistent with allocation and release of resources in a function and in an application. Error conditions should always be checked to make sure that resources are assigned and freed appropriately.
Vulnerable code example
#include <stdio.h>
#include <mqueue.h>
void message_unchecked(const char* name, const char* data1, const char* data2)
{
char c;
mqd_t h;
if ((h = mq_open(name, O_RDWR)) != (mqd_t)-1)
{
mq_receive(h, &c, 1, NULL);
if (c == '1')
mq_send(h, data1, strlen(data1)+1, 2);
else
if (c == '2')
mq_send(h, data2, strlen(data2)+1, 2);
}
else
{
fprintf(stderr, "'mq_open' failed for %s\n", name);
}
mq_close(h); // Handler status might be wrong here.
}
Klocwork produces a defect report for line 21, indicating that the handler resource may not be open at this point, depending on the foregoing code, in which case it can't be closed. Incorrect resource handling like this can cause software reliability problems.
Fixed code example
#include <stdio.h>
#include <mqueue.h>
void message_unchecked(const char* name, const char* data1, const char* data2)
{
char c;
mqd_t h;
if ((h = mq_open(name, O_RDWR)) != (mqd_t)-1)
{
mq_receive(h, &c, 1, NULL);
if (c == '1')
mq_send(h, data1, strlen(data1)+1, 2);
else
if (c == '2')
mq_send(h, data2, strlen(data2)+1, 2);
mq_close(h);
}
else
{
fprintf(stderr, "'mq_open' failed for %s\n", name);
}
}
In the fixed code example, handler 'h' is released in line 16, after the call to 'mq_send'.