Semmle 1.20
Skip to end of metadata
Go to start of metadata

Name: Open descriptor never closed

Description: Functions that always return before closing the socket or file they opened leak resources.

ID: cpp/descriptor-never-closed

Kind: problem

Severity: warning

Query: DescriptorNeverClosed.ql
/**
 * @name Open descriptor never closed
 * @description Functions that always return before closing the socket or file they opened leak resources.
 * @kind problem
 * @id cpp/descriptor-never-closed
 * @problem.severity warning
 * @tags efficiency
 *       security
 *       external/cwe/cwe-775
 */
import semmle.code.cpp.pointsto.PointsTo

predicate closed(Expr e)
{
  exists(FunctionCall fc |
    fc.getTarget().hasQualifiedName("close") and
    fc.getArgument(0) = e)
}

class ClosedExpr extends PointsToExpr
{
  ClosedExpr() { closed(this) }
  override predicate interesting() { closed(this) }
}

from Expr alloc
where allocateDescriptorCall(alloc)
  and not exists(ClosedExpr closed | closed.pointsTo() = alloc)
select alloc, "This file descriptor is never closed"

This rule finds calls to open or socket where there is no corresponding close call in the program analyzed. Leaving descriptors open will cause a resource leak that will persist even after the program terminates.

This check is an approximation, so some results may not be actual defects in the program. It is not possible in general to compute the exact value of the variable without running the program with all possible input data.

Recommendation

Ensure that all file or socket descriptors allocated by the program are freed before it terminates.

Example

In the example below, the sockfd socket remains open when the main program finishes. The code should be updated to ensure that the socket is always closed when the program terminates.

int main(int argc, char* argv[]) {
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	int status = 0;
	... //code that does not close sockfd
	return status; //sockfd is never closed
}

References