Несоответствующая операция I/O на файлах устройств

Операция может привести к уязвимостям системы обеспечения безопасности или системному отказу

Описание

Несоответствующая операция I/O на файлах устройств происходит, когда вы не проверяете, относится ли параметр имени файла к файлу устройств, прежде чем вы передадите его этим функциям:

  • fopen()

  • fopen_s()

  • freopen()

  • remove()

  • rename()

  • CreateFile()

  • CreateFileA()

  • CreateFileW()

  • _wfopen()

  • _wfopen_s()

Файлы устройств являются файлами в файловой системе, которые обеспечивают интерфейс к драйверам устройств. Можно использовать эти файлы, чтобы взаимодействовать с устройствами.

Несоответствующая операция I/O на файлах устройств не повышает дефект когда:

  • Вы используете stat или lstat - функции семейства, чтобы проверять параметр имени файла прежде, чем вызвать ранее перечисленные функции.

  • Вы используете функцию сравнения строк, чтобы сравнить имя файла со списком имен файла устройств.

Риск

Операции, подходящие только для регулярных файлов, но выполняемые на файлах устройств, могут привести к атакам "отказ в обслуживании", другим уязвимостям системы обеспечения безопасности или системным отказам.

Фиксация

Прежде чем вы выполните операцию I/O на файле:

  • Используйте stat(), lstat() или эквивалентную функцию, чтобы проверять, относится ли параметр имени файла к регулярному файлу.

  • Используйте функцию сравнения строк, чтобы сравнить имя файла со списком имен файла устройств.

Примеры

развернуть все

#include <stdio.h>
#include <string.h>

#define SIZE1024 1024

FILE* func()
{

    FILE* f;
    const char file_name[SIZE1024] = "./tmp/file";
    
    if ((f = fopen(file_name, "w")) == NULL) {
        /*handle error */
    };
    /*operate on file */
}

В этом примере func() управляет на файле file_name, не проверяя, является ли это регулярным файлом. Если file_name является файлом устройств, попытки получить доступ к нему могут привести к системному отказу.

Исправление — файл проверки с lstat() прежде, чем вызвать fopen()

Одно возможное исправление должно использовать lstat() и макрос S_ISREG, чтобы проверять, является ли файл регулярным файлом. Это решение содержит состояние состязания TOCTOU, которое может позволить атакующему изменять файл после того, как вы проверяете его, но перед вызовом fopen (). Чтобы предотвратить эту уязвимость, гарантируйте, что file_name относится к файлу в безопасной папке.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#define SIZE1024 1024

FILE* func()
{

    FILE* f;
    const char file_name[SIZE1024] = "./tmp/file";
    struct stat orig_st;
    if ((lstat(file_name, &orig_st) != 0) ||
        (!S_ISREG(orig_st.st_mode))) {
        exit(0);
    }
    if ((f = fopen(file_name, "w")) == NULL) {
        /*handle error */
    };
    /*operate on file */
} 

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

Группа: безопасность
Язык: C | C++
Значение по умолчанию: 'off'
Синтаксис командной строки: INAPPROPRIATE_IO_ON_DEVICE
Влияние: носитель
ID CWE: 67

Введенный в R2018b