Checkers:SV.INCORRECT_RESOURCE_HANDLING.URH

From current

Reference > C/C++ checkers > SV.INCORRECT RESOURCE HANDLING.URH

Insecure resource handling—allocation and release

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. This type of defect often occurs in function exits for exceptions or error handling.

The SV.INCORRECT_RESOURCE_HANDLING.URH checker flags situations in which a resource is requested after it may have been released. 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 is not 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.

Mitigation and prevention

It's good practice to ensure that all resources allocated are subsequently freed, and to be consistent with allocation and release of resources in a function and in an application. Error conditions, in particular, should always be checked to make sure that resources are assigned and freed appropriately.

Code examples

Vulnerable code example

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

Klocwork produces an issue report at line 20, indicating that handler 'h', which is the result of a call to 'mq_open', was used after it was released in line 18. 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_released(const char* name, const char* data1, const char* data2)
5   {
6  
7  	  char c;
8  	  mqd_t h;
9  	  if ((h = mq_open(name, O_RDWR)) != (mqd_t)-1)
10 	  {
11 			mq_receive(h, &c, 1, NULL);
12 			if (c == '1')
13 				 mq_send(h, data1, strlen(data1)+1, 2);
14 			else
15 
16 			if (c == '2')
17 				 mq_send(h, data2, strlen(data2)+1, 2);
18 			printf("OK.\n");
19 			mq_send(h, "OK.", 3, 2);
20 			mq_close(h);
21 	  }
22 	  else
23 	  {
24 			fprintf(stderr, "'mq_open' failed for %s\n", name);
25 
26 	  }
27  }

In the fixed code example, handler 'h' isn't released until line 21, after the call to 'mq_send'.

Related checkers

External guidance