メインコンテンツ

解放したポインターのリセットがありません

ポインター free の後に、残りのデータをクリアするリセット ステートメントが続いていない

説明

この欠陥は、ポインターが解放された後、別の値が再割り当てされない場合に発生します。ポインター解放後も、依然としてそのメモリ データにアクセスできます。このデータをクリアするために、このポインターにも NULL または他の値を設定しなければなりません。

リスク

ポインターをリセットしないと、使われないポインターがそのまま残る可能性があります。このようなポインターは以下の原因になる可能性があります。

  • 既に解放済みのメモリの解放。

  • 既に解放済みのメモリに対する読み取りまたは書き込み。

  • 解放済みポインターに保存されたコードまたは権限が脆弱なコードのハッカーによる実行。

修正方法

ポインターを解放後、すぐに別の有効なアドレスが割り当てられない場合は、そのポインターに NULL を設定します。

すべて展開する

#include <stdlib.h>
enum {
    SIZE3   = 3,
    SIZE20  = 20
};

void allocateAndFreeMemory()
{
    static char *str = NULL;

    if (str == NULL)
        str = (char *)malloc(SIZE20);

    if (str != NULL)
        free(str);
}

この例では、ポインター str がプログラムの最後で解放されています。次の allocateAndFreeMemory の呼び出しは、str が NULL でなく、NULL への初期化が無効になることがあるため、失敗する可能性があります。

修正 — free の再定義による解放とリセット

考えられる 1 つの修正方法として、ポインターの解放時に、ポインターが自動的にリセットされるように free をカスタマイズします。

#include <stdlib.h>
enum {
    SIZE3   = 3,
    SIZE20  = 20
};

static void sanitize_free(void **p)
{
    if ((p != NULL) && (*p != NULL))
    {
        free(*p);
        *p = NULL;
    }
}

#define free(X) sanitize_free((void **)&X)

void allocateAndFreeMemory()
{
    static char *str = NULL;

    if (str == NULL)
        str = (char *)malloc(SIZE20);

    if (str != ((void *)0))
    {
        free(str);
    }
}

結果情報

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

バージョン履歴

R2016b で導入