JPCERT コーディネーションセンター

INT07-C. 数値には符号の有無を明示した char 型のみを使用する

3つの型 charsigned char、および unsigned char を総称して文字型(character type)と呼ぶ。処理系は、char を、signed char または unsigned charいずれかと同じ値の範囲、同じ表現形式、そして同じ動作をするものとして定義しなければならない。char はどちらに定義されたとしても、signed char とも unsigned char とも異なる型であり、それらと互換性はない

文字型変数に数値を格納し、使用するには、signed char もしくは unsigned char 型のみを使うこと。この方法が唯一型の符号を保証できる手段である。文字の表現に関する詳細は、「STR00-C. 文字の表現には適切な型を使用する」を参照のこと。

違反コード

以下のコード例では、char 型の変数 c は符号付きかもしれないし、符号無しかもしれない。文字型が8ビットの2の補数表現であると仮定すると、このコードは i/c = 5 (符号無し) あるいは i/c = -17 (符号付き) のいずれかを出力する。これらの整数が符号付きであるか符号無しであるかを知らずして、プログラムの正しさを判断することは難しい。

char c = 200;
int i = 1000;
printf("i/c = %d\n", i/c);
適合コード

以下の適合コードでは、変数 cunsigned char として宣言している。つづく除算演算は char の符号に左右されることなく、予測可能な結果になる。

unsigned char c = 200;
int i = 1000;
printf("i/c = %d\n", i/c);
例外

INT07-EX1:FIO34-C. 文字入出力関数の返り値の取得には int 型を使用する」は int 型の返り値を返す文字入出力関数について言及している。これらの関数は返り値を算術型で返すが、値は本質的には数値ではないため、その値を後で char 型変数に格納してもよい。

リスク評価

コード上はごく小さなエラーだが、きわめて幅広い範囲の深刻な脆弱性を招く可能性がある。最低でも、このエラーが原因で異なるプラットフォームで予期せぬ数値になる可能性がある。予期せぬ整数値が配列やポインタに利用されると、バッファオーバーフローや無効なメモリアクセスを引き起こすおそれがある。

レコメンデーション

深刻度

可能性

修正コスト

優先度

レベル

INT07-C

P8

L2

自動検出

ツール

バージョン

チェッカー

説明

Compass/ROSE

 

 

このレコメンデーションの違反を検出できる。特に、(signed もしくは unsigned 修飾子がついていない) char 型の値が数式に出現すると警告を発する。

ECLAIR

1.1

idb_charplan

実装済み

Fortify SCA

5.0

 

CERT C Rule Packを使ってこのレコメンデーションの違反を検出できる

LDRA tool suite

V. 8.5.4

93 S
329 S
432 S
458 S

実装済み

Splint

V. 3.1.1

 

 

PRQA QA-C 8.1

3711
3722
3733
3744
3755
3766
3777
3788
3850
3863
3911
3922
3933
3944
3955
3966
3977
3988
4050
4063

部分的に実装済み
関連するガイドライン
CERT C++ Coding Standard INT07-CPP. Use only explicitly signed or unsigned char type for numeric values
ISO/IEC TR 24772:2013 Bit Representations [STR]
MISRA C:2012 Rule 10.1 (required)
Rule 10.3 (required)
Rule 10.4 (required)
MITRE CWE CWE-682, Incorrect calculation
翻訳元

これは以下のページを翻訳したものです。

INT07-C. Use only explicitly signed or unsigned char type for numeric values (revision 73)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter