CERT C: Rule FIO38-C

Не копировать объект ФАЙЛ

Описание

Определение правила

Не копируйте объект ФАЙЛ.[1]

Реализация Polyspace

Эта проверка проверяет на Неправильное использование объекта ФАЙЛ.

Примеры

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

Проблема

Неправильное использование объекта ФАЙЛ происходит, когда:

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

  • Весь объект ФАЙЛ или один из его компонентов изменяется с помощью указателя.

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

Риск

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

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

Не создавать копию объекта ФАЙЛ. Не используйте адрес объекта ФАЙЛ, который не был возвращен из успешного вызова в 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 dereferenced, и его содержимое копируется в 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 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

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

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