CERT C: правило FIO38-C

Не копируйте объект FILE

Описание

Управляйте определением

Не копируйте объект FILE. [1]

Примеры

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

Описание

Неправильное употребление объекта FILE происходит когда:

  • Вы разыменовываете указатель на объект FILE, включая косвенный разыменовывают при помощи memcmp().

  • Вы изменяете целый объект FILE или один из его компонентов через его указатель.

  • Вы берете адрес объекта FILE, который не был возвращен от вызова до fopen - функция семейства. Никакой дефект не повышен, если макрос задает указатель как адрес встроенного объекта FILE, такого как #define ptr (&__stdout).

Риск

В некоторых реализациях адрес указателя на объект FILE, используемый, чтобы управлять потоком, является значительным. Указатель на копию объекта FILE интерпретирован по-другому, чем указатель на исходный объект и может потенциально привести к операциям на неправильном потоке. Поэтому использование копии объекта FILE может заставить программное обеспечение прекращать отвечать, который атакующий может использовать в атаках "отказ в обслуживании".

Фиксация

Не делайте копию объекта FILE. Не используйте адрес объекта FILE, который не был возвращен от успешного вызова до fopen - функция семейства.

Пример - копия объекта ФАЙЛА, используемого в fputs()

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

void fatal_error(void);

int func(void)
{
	/*'stdout' dereferenced and contents
        copied to 'my_stdout'. */
    FILE my_stdout = *stdout;  
	
	/* Address of 'my_stdout' may not point to correct stream. */
    if (fputs("Hello, World!\n", &my_stdout) == EOF)  
    {
        /* Handler error */
        fatal_error();
    }
    return 0;
}
        
      

В этом примере объект FILE разыменовывается stdout, и его содержимое копируется в my_stdout. Содержимое stdout не может быть значительным. fputs() затем вызван адресом my_stdout в качестве аргумента. Поскольку никакой вызов fopen() или подобной функции не был выполнен, адрес my_stdout не может указать на правильный поток.

Исправление — копирует указатель объекта ФАЙЛА

Объявите, что my_stdout указывает на тот же адрес как stdout, чтобы гарантировать, что вы пишете в правильный поток, когда вы вызываете fputs().

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

void fatal_error(void);

int func(void)
{
	/* 'my_stdout' and 'stdout' point to the same object. */
    FILE *my_stdout = stdout;  
    if (fputs("Hello, World!\n", my_stdout) == EOF)
    {
        /* Handler error */
        fatal_error();
    }
    return 0;
} 

Проверяйте информацию

Группа: правило 09. Ввод-вывод (FIO)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.