C and C++


MISC.NEGCHAR : 負のキャラクタ値

要旨

負の(もしくは負となる可能性がある)値が、 unsigned char もしくは EOF (int型) の値を引数として渡すべき関数に渡されています。

プロパティ

クラス名 Negative Character Value
日本語クラス名 負のキャラクタ値
クラス分類 セキュリティ (security)
ニーモニック MISC.NEGCHAR
カテゴリー
MisraC2023 MisraC2023:21.13 Any value passed to a function in <ctype.h> shall be representable as an unsigned char or be the value EOF
  MisraC2023:22.7 The macro EOF shall only be compared with the unmodified return value from any Standard Library function capable of returning EOF
  MisraC2023:D.4.1 Run-time failures shall be minimized
Misra2012 Misra2012:21.13 Any value passed to a function in <ctype.h> shall be representable as an unsigned char or be the value EOF
  Misra2012:22.7 The macro EOF shall only be compared with the unmodified return value from any Standard Library function capable of returning EOF
  Misra2012:D.4.1 Run-time failures shall be minimized
AUTOSARC++14 AUTOSARC++14:A21-8-1 Arguments to character-handling functions shall be representable as an unsigned char.
CWE CWE:681 Incorrect Conversion between Numeric Types
  CWE:686 Function Call With Incorrect Argument Type
TS17961 TS17961:5.16-signconv 5.16. Conversion of signed characters to wider integer types before a check for EOF
  TS17961:5.31-chrsgnext 5.31. Passing arguments to character-handling functions that are not representable as unsigned char
CERT-C CERT-C:INT05-C Do not use input functions to convert character data if they cannot handle all possible inputs
  CERT-C:STR00-C Represent characters using an appropriate type
  CERT-C:STR34-C Cast characters to unsigned char before converting to larger integer sizes
  CERT-C:STR37-C Arguments to character-handling functions must be representable as an unsigned char
対応言語 C および C++ で利用可能です。
有効/無効設定 このワーニングクラスのチェックはデフォルトで有効になっています。チェックを無効にするにはプロジェクト設定ファイル (configuration file)に以下の WARNING_FILTER ルールを追加してください。
WARNING_FILTER += discard class="Negative Character Value"

#include <stdio.h>
#include <ctype.h>

void f(const char *instr, int len){
    int i;
    /* ... obtain instr and len */ 
    for (i=0; i<len; i++){
        if (isupper(instr[i])){    /* Negative Character Value warning issued here */
            printf("string has upper case character");
        }
    }

    /* do this instead */
    for (i=0; i<len; i++){
        if (isupper( (unsigned char) instr[i] )){   
            printf("string has upper case character");
        }
    }
}

注釈

ctype.h で定義されている、キャラクタの分類および変換関数の仕様では、 unsigned char および EOF が表現が可能な int の引数が要求されています。 符号付き char の引数が使用された場合、 int 値が負でも EOF でもない場合は未定義動作につながります。

多くの libc 実装では、以下の様に関数はルックアップテーブルを使って実装されています。

  #define islower(x) (_ctype_info[(int)(x) + 1] & _LOCALE)

この様な定義では、 islower() が符号付きキャラクタ引数で呼ばれた場合、重大な問題を引き起こします。

char c;
if (scanf("%c", &c)){
    if (islower(c)){ /*...*/

攻撃者は '\156' (= (char)-100, これは拡張 ASCII では 'S' となります) のような負のキャラクタ値を渡す可能性があります。これによりルックアップテーブルはバッファのアンダーフローを引き起こし、テーブルの開始位置から 99 バイト前の位置のメモリ情報を出力します。攻撃者は徐々にこの値を減少させ、 127 バイトのメモリブロックの全ての内容を取得可能です。 このブロックには、重要な情報を含んでいるかもしれません。

幾つかのlibc 実装はルックアップテーブルを使用していませんが、負のキャラクタ引数は関数定義に違反しています。 もし符号付き char 値をこれらの関数で使うときは、事前に unsigned char にキャストする必要があります。

ワーニングを引き起こす関数

CodeSonar ships with library models that allow it to functions such as libc tolower() that expect an argument representable as unsigned char. If one of these functions is called with an unsuitable value in the relevant parameter position, a warning will be issued.

If you have created a custom library model for some function f() in terms of one of these existing models, calls to f() will also be capable of triggering Negative Character Value warnings.

関連のある設定ファイルパラメータ

設定ファイルの以下のパラメータがこのワーニングクラスのチェックに影響します。