メインコンテンツ

ISO/IEC TS 17961 [libmod]

getenv、localeconv、setlocale、および strerror が返す文字列の変更

説明

ルール定義

getenv、localeconv、setlocale、および strerror が返す文字列の変更。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);
        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);
    }
}

チェック情報

決定可能性:決定不可能

バージョン履歴

R2019a で導入


1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.