Misuse of readlink()

Третий аргумент readlink не оставляет пространства для null terminator в буфере

Описание

Этот дефект возникает, когда вы передаете аргумент buffer size в readlink() это не оставляет пространства для ядра терминатор строки в буфере.

Для образца:

ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf));
Третий аргумент в точности равен размеру второго аргумента. Для достаточно большие символические ссылки это использование readlink() не оставляет пространства, чтобы ввести null terminator.

Риск

The readlink() функция копирует содержимое символьной ссылки (первый аргумент) в буфер (второй аргумент). Однако функция не добавляет null terminator к скопированному содержимому. После использования readlink()необходимо явным образом добавить к буферу терминатор строки.

Если вы заполняете весь буфер при использовании readlink, вы не оставляете пространства для этого нулевого терминатора строки.

Зафиксировать

При использовании readlink() убедитесь, что третий аргумент на единицу меньше buffer size.

Затем добавьте null terminator к буферу. Чтобы определить, где добавить ядро терминатора строки, проверьте возврат значение readlink(). Если возврат значение -1, произошёл ошибка. В противном случае возврат значение является количеством скопированных символов (байтов).

Примеры

расширить все

#include <unistd.h>

#define SIZE1024 1024

extern void display_path(const char *);

void func() {
    char buf[SIZE1024];
    ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf));
    if (len > 0) {
        buf[len - 1] = '\0';
    }
    display_path(buf);
}

В этом примере третий аргумент readlink - точный размер буфера (второй аргумент). Если первый аргумент достаточно длинный, это использование readlink не оставляет пространства для null terminator.

Кроме того, если никакие символы не копируются, возврат значение readlink равен 0. Следующий оператор приводит к подтексту буфера при len равен 0.

buf[len - 1] = '\0';

Коррекция - убедитесь, что аргумент в размере на один меньше, чем Buffer size

Одна из возможных коррекций состоит в том, чтобы убедиться, что третий аргумент readlink меньше, чем размер второго аргумента.

Следующий исправленный код также учитывает readlink возврат 0.

#include <stdlib.h>
#include <unistd.h>

#define fatal_error() abort()
#define SIZE1024 1024

extern void display_path(const char *);

void func() {
    char buf[SIZE1024];
    ssize_t len = readlink("/usr/bin/perl", buf, sizeof(buf) - 1); 
    if (len != -1) {
        buf[len] = '\0';
        display_path(buf);
    }
    else {
        /* Handle error */
        fatal_error();
    }
}

Информация о результатах

Группа: Безопасность
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки: READLINK_MISUSE
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 170
Введенный в R2017a