EXP16-C. 関数ポインタを定数値と比較しない
関数ポインタを同じ型の NULL でない関数ポインタの値と比較すると診断の対象となる。通常これはプログラマが間違いを犯したことを示唆しており、未定義の動作を引き起こす可能性がある。暗黙的な比較も診断の対象となる。
違反コード
以下のコード例では、POSIX 関数 getuid
および geteuid
のアドレスが 0 と等しいかを比較している。関数のアドレスが NULL になることはないため、最初の部分式は常に偽 (ゼロ) であり、2 番目の部分式は常に真 (非ゼロ) となる。ゆえに、式全体は常に真となり、セキュリティ上の脆弱性につながる可能性がある。
/* 本来は root に対してのみ許可されているオプション */ if (getuid == 0 || geteuid != 0) { /* ... */ }
違反コード
以下のコード例では、関数ポインタ getuid
および geteuid
を 0 と比較している。
以下のコード例は、X Window System サーバのいくつかのバージョンで発見された実際の脆弱性(VU#837857)からの引用である。関数識別子 geteuid
の後にプログラマが開き括弧と閉じ括弧を付け損ねているために脆弱性が存在している。geteuid
は関数のアドレスを返すが、決して 0 にはならない。ゆえに、この if
文の OR
条件は常に真となり、許可されていない領域へのアクセスがすべてのユーザに許されてしまう。多くのコンパイラは、このような無意味な式を指摘する警告を発行する。このため、このコーディングエラーは、「MSC00-C. 高い警告レベルで警告を出さずにコンパイルする」に従うことで通常は検出される。
/* 本来は root に対してのみ許可されているオプション */ if (getuid() == 0 || geteuid != 0) { /* ... */ }
適合コード
解決策は、関数識別子 geteuid
の後に開き括弧と閉じ括弧を付け、関数が正しく呼び出されるように修正することである。
/* 本来は root に対してのみ許可されているオプション */ if (getuid() == 0 || geteuid() != 0) { /* ... */ }
適合コード
関数ポインタは、同じ型の NULL の関数ポインタと比較できる。
/* 本来は root に対してのみ許可されているオプション */ if (getuid == (uid_t(*)(void))0 || geteuid != (uid_t(*)(void))0) { /* ... */ }
このコードは、解析ツールによる診断の対象になることはない。
違反コード
次のコード例では、関数ポインタ do_xyz
が 0 と等しくないことを暗黙的に比較している。
int do_xyz(void); if (do_xyz) { /* エラー処理 * / }
適合コード
次の適合コードでは、関数 do_xyz()
を呼び出し、返り値を 0 と比較している。
int do_xyz(void); if (do_xyz()) { /* エラー処理 * / }
リスク評価
必要な文字を書き忘れると、意図しないプログラムフローを引き起こすことがある。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
EXP16-C |
低 |
高 |
中 |
P6 |
L2 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
Coverity |
6.5 |
BAD_COMPARE |
「処理系固有の詳細」に示した |
GCC | V. 4.3.5 |
|
|
V. 9.1 |
EFFECT |
||
LDRA tool suite |
V. 8.5.4 |
関連するガイドライン
CERT C++ Secure Coding Standard | EXP16-CPP. Avoid conversions using void pointers |
ISO/IEC TR 24772:2013 | Likely incorrect expressions [KOA] |
ISO/IEC TS 17961 (ドラフト) | Comparing function addresses to zero [funcaddr] |
MITRE CWE | CWE-480, Use of incorrect operator CWE-482, Comparing instead of assigning |
参考資料
[Hatton 1995] | Section 2.7.2, "Errors of Omission and Addition" |
翻訳元
これは以下のページを翻訳したものです。
EXP16-C. Do not compare function pointers to constant values (revision 32)