exponenta event banner

Утечка информации через заполнение структуры

Заполняющие байты могут содержать конфиденциальную информацию

Описание

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

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

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

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

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

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

Риск

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

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

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

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

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

Примеры

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

#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 Pragma для предотвращения заполнения байтов

Одной из возможных корректировок в Microsoft ® Visual Studio ® является использование#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);
}

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

Группа: Безопасность
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: PADDING_INFO_LEAK
Воздействие: Низкий
Представлен в R2018a