メインコンテンツ

メモリの操作に使用するオブジェクトのサイズがハードコードされています

sizeof の代わりにサイズがハードコードされているメモリ操作

説明

この欠陥は、ハードコードされている定数を次のメモリ関数のメモリ サイズ引数として使用する場合に発生します。

  • malloccalloc などの動的メモリ割り当て関数。

  • memcpymemmovememcmpmemset などのメモリ操作関数。

メモリ サイズをハードコードしている場合、文字列リテラルを使用してメモリ操作を実行すると、Polyspace® は欠陥を報告しません。

リスク

オブジェクトのサイズをハードコードすると、コードが、型のサイズが異なるアーキテクチャに移植できません。定数値がオブジェクトのサイズと同じでない場合、バッファーがオーバーフローしたり、しなかったりする可能性があります。

修正方法

メモリ関数のサイズ引数には、sizeof(object) を使用します。

すべて展開する

#include <stddef.h>
#include <stdlib.h>
enum {
    SIZE3   = 3,
    SIZE20  = 20
};
extern void fill_ints(int **matrix, size_t nb, size_t s);

void bug_hardcodedmemsize()
{
    size_t i, s;

    s = 4;
    int **matrix = (int **)calloc(SIZE20, s);
    if (matrix == NULL) {
        return; /* Indicate calloc() failure */
    }
    fill_ints(matrix, SIZE20, s);
    free(matrix);
}

この例では、メモリ割り当て関数 calloc が 4 バイトのメモリ サイズで呼び出されています。このメモリは整数ポインターに対して割り当てられています。整数ポインターは、ターゲットによって 4 バイトよりも大きい場合も小さい場合もあります。整数型ポインターが 4 バイトでない場合、プログラムは失敗する可能性があります。

修正 — sizeof(int *) を使用

calloc を呼び出す際、ハード コードしているサイズを sizeof の呼び出しに置き換えます。この変更によりコードの移植性が高くなります。

#include <stddef.h>
#include <stdlib.h>
enum {
    SIZE3   = 3,
    SIZE20  = 20
};
extern void fill_ints(int **matrix, size_t nb, size_t s);

void corrected_hardcodedmemsize()
{
    size_t i, s;

    s = sizeof(int *);
    int **matrix = (int **)calloc(SIZE20, s);
    if (matrix == NULL) {
        return; /* Indicate calloc() failure */
    }
    fill_ints(matrix, SIZE20, s);
    free(matrix);
}

この例では、関数 clean_sensitive_memory が機密情報をメモリからクリアします。ここで、memset のメモリ サイズ引数は 64 バイトとしてハードコードされています。s->data64 バイトを格納できない場合、プログラムは失敗し、機密情報がメモリに残る可能性があります。Polyspace はメモリ操作での欠陥を報告します。

#include<string.h>

struct sensitiveInfo
{
    unsigned char data[64];
    int length;
};

char key[64];

void clean_sensitive_memory (struct sensitiveInfo *s)
{
    memset (s->data, 0, 64);          //Defect
    memset ((void *) key, 0, 64);  //Defect
}

修正 — サイズ引数に sizeof() を使用

この欠陥を修正するには、ハードコードされているメモリ サイズを sizeof() の呼び出しに置き換えます。

#include<string.h>

struct sensitiveInfo
{
    unsigned char data[64];
    int length;
};

char key[64];

void clean_sensitive_memory (struct sensitiveInfo *s)
{
  memset (s->data, 0, sizeof (s->data));	//Fixed
  memset ((void *) key, 0, sizeof(key)); //Fixed
}

結果情報

グループ: 適切な手法
言語: C | C++
既定値: オフ
コマンド ライン構文: HARD_CODED_MEM_SIZE
影響度: Low

バージョン履歴

R2016b で導入

すべて展開する