c.lang.security.random-fd-exhaustion.random-fd-exhaustion

Community Favorite
profile photo of semgrepsemgrep
Author
46,010
Download Count*

Call to 'read()' without error checking is susceptible to file descriptor exhaustion. Consider using the 'getrandom()' function.

Run Locally

Run in CI

Defintion

rules:
  - id: random-fd-exhaustion
    pattern-either:
      - patterns:
          - pattern: |
              $FD = open("/dev/urandom", ...);
              ...
              read($FD, ...);
          - pattern-not: |
              $FD = open("/dev/urandom", ...);
              ...
              $BYTES_READ = read($FD, ...);
      - patterns:
          - pattern: |
              $FD = open("/dev/random", ...);
              ...
              read($FD, ...);
          - pattern-not: |
              $FD = open("/dev/random", ...);
              ...
              $BYTES_READ = read($FD, ...);
    message: Call to 'read()' without error checking is susceptible to file
      descriptor exhaustion. Consider using the 'getrandom()' function.
    metadata:
      cwe:
        - "CWE-774: Allocation of File Descriptors or Handles Without Limits or
          Throttling"
      references:
        - https://lwn.net/Articles/606141/
      category: security
      technology:
        - c
      confidence: MEDIUM
      subcategory:
        - audit
      likelihood: LOW
      impact: HIGH
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Denial-of-Service (DoS)
    languages:
      - c
    severity: WARNING

Examples

random-fd-exhaustion.c

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int bad_code1() {
    int fd;
    char buf[16];

    // ruleid: random-fd-exhaustion
    fd = open("/dev/urandom", 0);
    memset(buf, 0, sizeof(buf));
    read(fd, buf, sizeof(buf));

    return 0;
}

int okay_code1() {
    int fd;
    int bytes_read;
    char buf[16];

    // ok: random-fd-exhaustion
    fd = open("/dev/urandom", 0);
    memset(buf, 0, sizeof(buf));
    bytes_read = read(fd, buf, sizeof(buf));
    if (bytes_read != sizeof(buf)) {
        return -1;
    }

    return 0;
}

int bad_code2() {
    int fd;
    char buf[16];

    // ruleid: random-fd-exhaustion
    fd = open("/dev/random", 0);
    memset(buf, 0, sizeof(buf));
    read(fd, buf, sizeof(buf));

    return 0;
}

int okay_code2() {
    int fd;
    int bytes_read;
    char buf[16];

    // ok: random-fd-exhaustion
    fd = open("/dev/random", 0);
    memset(buf, 0, sizeof(buf));
    bytes_read = read(fd, buf, sizeof(buf));
    if (bytes_read != sizeof(buf)) {
        return -1;
    }

    return 0;
}