メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

構造体のパディングによる情報漏洩

パディング バイトに含まれる可能性のある機密情報

説明

このチェッカーは、既定の Polyspace® as You Code 解析では非アクティブにされますPolyspace as You Code 解析で非アクティブにされるチェッカー (Polyspace Access)を参照してください。

この欠陥は、構造体または共用体のパディング データを、信頼の境界を越えて渡す前に初期化していない場合に発生します。コンパイラによって構造体または共用体にパディング バイトが追加されることにより、そのメンバーの適切なメモリ アライメントを確保します。そのストレージ ユニットのビット フィールドにもパディング ビットが含まれる可能性があります。

[構造体のパディングによる情報漏洩] は、以下の場合に欠陥を報告します。

  • 初期化されていないパディング データが含まれた構造体または共用体のポインター型の引数を使用して、信頼されていない関数を呼び出した。

    すべての外部関数が信頼されていないと見なされます。

  • 初期化されていないパディング データが含まれた構造体または共用体を、信頼されていないオブジェクトにコピーまたは代入した。

    すべての外部構造体または共用体オブジェクト、すべての外部にリンクされた関数の出力パラメーター、およびすべての外部関数の戻り値のポインターが、信頼されていないオブジェクトと見なされます。

リスク

渡された構造体または共用体のパディング バイトに機密情報が含まれる場合があり、これらの情報が信頼されていないソースからアクセスされる可能性があります。

修正方法

  • 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 メンバーの間にパディング バイトが含まれる可能性があります。この構造体のストレージ ユニットのビット フィールドにも、パディング ビットが含まれる可能性があります。パディング バイトおよびビットの中身は、s1func に渡されるときに信頼されていないソースからアクセスできるようになります。

修正 — パディング バイトを防ぐために pack プラグマを使用

Microsoft® Visual Studio® での 1 つの修正方法として、#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 explicitly 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
影響度: Low

バージョン履歴

R2018a で導入