メインコンテンツ

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

CERT C: Rec.MEM01-C

free() の直後にポインターに新しい値を保存する

説明

ルール定義

free() の直後にポインターに新しい値を保存します。1

Polyspace 実装

ルール チェッカーは、"解放したポインターのリセットがありません" をチェックします。

すべて展開する

問題

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

リスク

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

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

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

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

修正方法

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

例 - リセットなしの解放
#include <stdlib.h>
enum {
    SIZE3   = 3,
    SIZE20  = 20
};

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

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

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

この例では、ポインター str がプログラムの最後で解放されています。次の bug_missingfreedptrrese の呼び出しは、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 missingfreedptrreset()
{
    static char *str = NULL;

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

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

チェック情報

グループ: Rec.08.メモリ管理 (MEM)

バージョン履歴

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.