Safeguard
Application Security•

CWE-910 Use of Expired File Descriptor: Causes and Fixes

Using a file descriptor after closing it can read or write the wrong file, or crash the program. Here is why it happens and how to stop it.

Safeguard Security Team
2 min read

CWE-910, Use of Expired File Descriptor, is what happens when code uses a file descriptor after it has been closed. It matters mostly in C and C++, but the idea applies to any code that holds a raw handle to a file, socket or device.

How it happens

When a descriptor is released, the operating system is free to hand the same number out again. If your code still holds the old number, it now points at whatever got opened next. MITRE puts it plainly: the code might not write to the original file, because the reused descriptor might reference a different file or device.

A typical shape is a cleanup path that closes a descriptor on error, then a later code path that uses the same variable.

int fd = open(path, O_RDONLY);
if (fd < 0) return -1;
if (parse_header(fd) != 0) {
    close(fd);          /* closed here */
}
read(fd, buf, len);     /* used after close: expired descriptor */

What an attacker gains

MITRE lists two consequences. Confidentiality: the program could read data from the wrong file. Availability: using a closed descriptor can cause a crash. Whether an attacker can steer which file gets the recycled number depends on the program, so treat it as a real exposure when the process handles untrusted input.

How to find it

MITRE notes that static analysis, or SAST, can find some instances by modeling data flow and control flow through the code, and rates its effectiveness as high. A code review that follows each descriptor from open to every close is the manual version.

How to fix it

The MITRE record lists no formal mitigations. Practical steps:

  1. Set the variable to an invalid value, such as negative one, immediately after closing it, and check before use.
  2. Close each descriptor in exactly one place, ideally with a single cleanup label.
  3. In C++, wrap descriptors in an object that closes them on destruction so the code cannot reuse a raw number.

Quick check

Why is a closed descriptor more than a crash risk?

Because the number can be reused. A later read or write may land on a different file or device than the one you meant.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.