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

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

Описание

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

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

Примеры

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

Описание

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

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

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

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

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

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

Риск

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

Фиксация

  • Предотвратите сложение дополнения байтов для выравнивания памяти при помощи прагмы 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 может иметь дополнительные байты между участниками int i и char c. Битовые поля устройств хранения данных структуры могут также содержать дополнительные биты. Содержимое дополнительных байтов и битов доступно для недоверяемого источника, когда s1 передается func.

Исправление — использует прагму pack, чтобы предотвратить дополнительные байты

Одно возможное исправление в Microsoft® Visual Studio®is, чтобы использовать #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 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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