Information leak via structure padding

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

Описание

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

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

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

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

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

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

Риск

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

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

  • Предотвратите сложение байтов заполнения для выравнивания памяти при помощи 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);
}

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

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