メインコンテンツ

CERT C: Rule ENV30-C

Do not modify the object referenced by the return value of certain functions

説明

ルール定義

特定の関数の戻り値によって参照されるオブジェクトを変更しないようにします。1

Polyspace 実装

ルール チェッカーは、"再呼び出し不可能な標準関数から返された内部バッファーが変更されています" をチェックします。

すべて展開する

問題

再呼び出し不可能な標準関数から返された内部バッファーが変更されていますは、以下の場合に発生します。

  • 再呼び出し不可能な標準関数がポインターを返す。

  • ポインターが指すメモリ位置に書き込みを試みている。

const 修飾子付きでない内部バッファーへのポインターを返す再呼び出し不可能な標準関数には、getenvgetlogincryptsetlocalelocaleconvstrerror などがあります。

リスク

再呼び出し不可能な標準関数が返す内部バッファーの変更は、次の問題の原因となることがあります。

  • 変更が正常に終了しないか、他の内部データが変更される可能性がある。

    たとえば、getenv は環境変数値を指すポインターを返します。この値を変更すると、プロセスの環境が変更され、他の内部データが破損します。

  • 変更が正常に終了した場合でも、同じ標準関数をその後呼び出すと、変更された値が返されない可能性がある。

    たとえば、getenv によって返された環境変数の値が変更されたとします。別のプロセス、スレッドまたは信号ハンドラーが setenv を呼び出すと、変更された値は上書きされます。したがって、getenv をその後呼び出しても、変更された値は返されません。

修正方法

関数から返されるポインターを使用した内部バッファーの変更を回避します。

例 - getenv の戻り値の変更
#include <stdlib.h>
#include <string.h>

void printstr(const char*);

void func() {
    char* env = getenv("LANGUAGE");
    if (env != NULL) {
        strncpy(env, "C", 1); //Noncompliant
        printstr(env);
    }
}

この例では、strncpy の最初の引数は、再呼び出し不可能な標準関数 getenv からの戻り値です。この引数が strncpy で変更されるため、動作は未定義となることがあります。

修正 - getenv の戻り値をコピーして、コピーを変更

1 つの解決策として、getenv の戻り値をコピーし、そのコピーを関数 strncpy に渡すことができます。

#include <stdlib.h>
#include <string.h>
enum {
    SIZE20 = 20
};

void printstr(const char*);

void func() {
    char* env = getenv("LANGUAGE");
    if (env != NULL) {
        char env_cp[SIZE20];
        strncpy(env_cp, env, SIZE20);  
        strncpy(env_cp, "C", 1);        
        printstr(env_cp);
    }
}

チェック情報

グループ: Rule 10.環境 (ENV)

バージョン履歴

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.