CERT C: Rule DCL39-C

Избегайте утечек информации при заполнении конструкции

Описание

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

Избегайте утечек информации при заполнении конструкции.[1]

Реализация Polyspace

Эта проверка проверяет утечку информации через заполнение структуры.

Примеры

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

Проблема

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

Утечка информации через заполнение конструкции вызывает дефект, когда:

  • Вы вызываете ненадежную функцию со структурой или аргументом типа указателя объединения, содержащим неинициализированные данные заполнения.

    Все внешние функции считаются ненадежными.

  • Вы копируете или назначаете структуру или объединение, содержащее неинициализированные данные заполнения, ненадежному объекту.

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

Риск

Байты заполнения переданной структуры или объединения могут содержать конфиденциальную информацию, к которой может получить доступ ненадежный источник.

Зафиксировать
  • Предотвратите сложение байтов заполнения для выравнивания памяти при помощи pack прагма или атрибут, поддерживаемые вашим компилятором.

  • Явное объявление и инициализация заполнения байтов как полей в структуре или объединении.

  • Явное объявление и инициализация битовых полей, соответствующих битам заполнения, даже если вы используете pack прагма или атрибут, поддерживаемые вашим компилятором.

Пример - Структура с заполненными байтами, переданными во внешнюю функцию
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

typedef struct s_padding
{
 /* Padding bytes may be introduced between
 * 'char c' and 'int i'
 */
        char c;
    int i;

/*Padding bits may be introduced around the bit-fields
* even if you use "#pragma pack" (Windows) or
* __attribute__((__packed__)) (GNU)*/

    unsigned int bf1:1;
    unsigned int bf2:2;
    unsigned char buffer[20];
} S_Padding ;



/* External function */
extern void copy_object(void *out, void *in, size_t s);

void func(void *out_buffer)
{
/*Padding bytes not initialized*/

    S_Padding s = {'A', 10, 1, 3, {}};
/*Structure passed to external function*/

    copy_object((void *)out_buffer, (void *)&s, sizeof(s));
}

void main(void)
{
    S_Padding s1;
    func(&s1);
}

В этом примере структура s1 может иметь байты заполнения между char c и int i представителей. Битовые поля модулей структуры могут также содержать биты заполнения. Содержимое заполняющих байтов и бит доступно ненадежному источнику при s1 передается в func.

Коррекция - Использование pack Прагма для предотвращения заполнения байтов

Одна возможная коррекция в Microsoft® Визуальная студия® - использовать #pragma pack() чтобы предотвратить заполнение байтов между представителями структуры. Чтобы предотвратить заполнение бит в битовых полях s1, явным образом объявить и инициализировать битовые поля, даже если вы используете #pragma pack().

 #include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#define CHAR_BIT 8

#pragma pack(push, 1)   

typedef struct s_padding
{
/*No Padding bytes when you use "#pragma pack" (Windows) or
* __attribute__((__packed__)) (GNU)*/   
	char c;
    int i;               
    unsigned int bf1:1;
    unsigned int bf2:2;
/* Padding bits explicitely declared */
    unsigned int bf_filler : sizeof(unsigned) * CHAR_BIT - 3; 
    unsigned char buffer[20];
}

    S_Padding;

#pragma pack(pop)


/* External function */
extern void copy_object(void *out, void *in, size_t s);



void func(void *out_buffer)
{
    S_Padding s = {'A', 10, 1, 3, 0 /* padding bits */, {}};
    copy_object((void *)out_buffer, (void *)&s, sizeof(s)); 
}

void main(void)
{
    S_Padding s1;
    func(&s1);
}

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

Группа: Правило 02. Объявления и инициализация (DCL)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

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

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