Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

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

1   #include <stdio.h>
2   #include <mqueue.h>
3  
4   void message_unchecked(const char* name, const char* data1, const char* data2)
5   {
6         char c;
7         mqd_t h;
8         if ((h = mq_open(name, O_RDWR)) != (mqd_t)-1)
9         {
10                      mq_receive(h, &c, 1, NULL);
11                      if (c == '1')
12                               mq_send(h, data1, strlen(data1)+1, 2);
13                      else
14                      if (c == '2')
15                               mq_send(h, data2, strlen(data2)+1, 2);
16        }
17        else
18        {
19                      fprintf(stderr, "'mq_open' failed for %s\n", name);
20        }
21        mq_close(h); // Handler status might be wrong here.
22  }

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

1   #include <stdio.h>
2   #include <mqueue.h>
3  
4   void message_unchecked(const char* name, const char* data1, const char* data2)
5   {
6         char c;
7         mqd_t h;
8         if ((h = mq_open(name, O_RDWR)) != (mqd_t)-1)
9         {
10                      mq_receive(h, &c, 1, NULL);
11                      if (c == '1')
12                               mq_send(h, data1, strlen(data1)+1, 2);
13                      else
14                      if (c == '2')
15                               mq_send(h, data2, strlen(data2)+1, 2);
16        mq_close(h);
17        }
18        else
19        {
20                      fprintf(stderr, "'mq_open' failed for %s\n", name);
21        } 
22  }

In the fixed code example, handler 'h' is released in line 16, after the call to 'mq_send'.