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

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

Описание

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

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

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

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

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

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

Риск

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

Фиксация

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

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

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

Введенный в R2018a