メインコンテンツ

CERT C: Rule DCL39-C

Avoid information leakage in structure padding

説明

ルール定義

構造体のパディングにおける情報漏洩を回避します。1

Polyspace 実装

ルール チェッカーは、"構造体のパディングによる情報漏洩" をチェックします。

すべて展開する

問題

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

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

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

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

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

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

リスク

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

修正方法
  • 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)); //Noncompliant
}

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

チェック情報

グループ: Rule 02.宣言と初期化 (DCL)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.