メインコンテンツ

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

CERT C: Rule EXP42-C

パディング データを比較しない

説明

ルール定義

パディング データを比較しないようにします。1

Polyspace 実装

ルール チェッカーは、"パディング データのメモリ比較" をチェックします。

すべて展開する

問題

パディング データのメモリ比較は、関数 memcmp を使用して、2 つの構造体全体を比較する場合に発生します。この処理では、構造体のパディングで格納された無意味なデータが比較されます。

次に例を示します。

typedef struct structType {
    char member1;
    int member2;
    //...
}myStruct;

myStruct var1;
myStruct var2;
//...
if(memcmp(&var1,&var2,sizeof(var1))) 
{//...}

リスク

構造体のメンバーが異なるデータ型を持っている場合、コンパイラはメモリ内のデータ アライメントのために追加のパディングを導入します。パディングの例については、ローカル変数サイズのより高い推定値 (Polyspace Code Prover)を参照してください。

これらの追加のパディング バイトの内容に意味はありません。C 標準では、さまざまなコンパイラが独自のパディングを自由に実装できるように、それらのバイトのコンテンツが不確定になることを許容しています。memcmp で構造体のバイト単位の比較を実行する場合、パディングに格納された意味のないデータも比較されます。対応するメンバーが同じ値であっても、2 つのデータ構造体が等しくないという誤った結論になる可能性があります。

修正方法

2 つの構造体を 1 回の試行で比較するのではなく、構造体のメンバーごとに比較します。

効率的なコードにするには、メンバーごとに比較を行う関数を作成します。2 つの構造体を比較するには、この関数を使用します。

構造体がパディングを含まないことがわかっている場合のみ、構造体のバイト単位の比較に memcmp を使用します。通常、パディングが行われないようにするには、特定の属性または #pragma pack などのプラグマを使用します。ただし、このような属性やプラグマは、必ずしもすべてのコンパイラでサポートされているとは限らず、コードの実装はそれぞれ異なります。構造体にビット フィールドが含まれる場合、このような属性やプラグマを使用しても、パディングを防ぐことはできません。

例 - memcmp を使用した構造体の比較
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define fatal_error() abort()

typedef struct s_padding
{
    char c;            
    int i;
    unsigned int bf1:1;    
    unsigned int bf2:2;
    unsigned char buffer[20];
} S_Padding ;

/* Function that guarantees safe access to the input memory */
extern int trusted_memory_zone(void *ptr, size_t sz); 

int func(const S_Padding *left, const S_Padding *right)
{

    if (!trusted_memory_zone((void *)left, sizeof(S_Padding)) ||
        !trusted_memory_zone((void *)right, sizeof(S_Padding))) {
        fatal_error();
    }

    if (0 == memcmp(left, right, sizeof(S_Padding)))  //Noncompliant
    {
        return 1;
    }
    else
        return 0;
}

この例では、memcmp を使用して left および right が指す 2 つの構造体をバイト単位で比較しています。構造体の各メンバーに格納された値が同じでも、パディング バイトに使われる意味のない値が同じでなければ、この比較によって等しくないという結果になる可能性があります。

修正 — メンバーごとに構造体を比較

1 つの修正方法として、構造体のメンバーを個別に比較します。

メモ

memcmp を使用して、配列全体を比較できます。配列のメンバーはすべてデータ型が同じです。配列の格納にはパディング バイトは必要ありません。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define fatal_error() abort()

typedef struct s_padding
{
    char c;         
    int i;
    unsigned int bf1:1;    
    unsigned int bf2:2;
    unsigned char buffer[20];
} S_Padding ;

/* Function that guarantees safe access to the input memory */
extern int trusted_memory_zone(void *ptr, size_t sz); 

int func(const S_Padding *left, const S_Padding *right)
{
    if (!trusted_memory_zone((void *)left, sizeof(S_Padding)) ||
        !trusted_memory_zone((void *)right, sizeof(S_Padding))) {
        fatal_error();
    }

    return ((left->c == right->c) &&                
            (left->i == right->i) &&
            (left->bf1 == right->bf1) &&
            (left->bf2 == right->bf2) &&
            (memcmp(left->buffer, right->buffer, 20) == 0)); 
}

チェック情報

グループ: Rule 03.式 (EXP)

バージョン履歴

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.