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® 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);
}

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

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