API07-C. 型の安全性を徹底する
関数が返すオブジェクトは、必ず返り値の型に合致した有効なオブジェクトでなければならない。また、ポインタ型引数が指すオブジェクトを関数が変更する場合、変更後のオブジェクトは必ず引数の型に合致した有効なものでなければならない。そうしないと、プログラム内で型に関するエラーが発生するかもしれない。
C 言語の null 終端バイト文字列はその好例である。文字列が null 文字で終端されていない場合、プログラムは文字列の後ろの領域を正当なデータだと思ってアクセスしてしまう可能性がある。その結果、本来処理すべきでない文字列が処理され、このこと自体がセキュリティホールとなりかねない。プログラムの異常終了が引き起こされると、サービス運用妨害(denial-of-service)攻撃にもつながる。
このルールで強調したいのは、終端されていない文字列の生成を避けることであり、既に存在する null 終端されていない文字列をどう処理すべきかということについては議論しない。そうは言っても、null 終端されていない文字列を作成しなければ、そのような文字列を処理する必要性は大幅に減るだろう。
違反コード
標準ライブラリの strncpy()
関数は、コピーした文字列が null 終端されることを保証しない。source
配列の最初の n
文字に null 文字がない場合、結果は null 終端されない可能性がある。
char *source; char a[NTBS_SIZE]; /* ... */ if (source) { char* b = strncpy(a, source, 5); // b == a } else { /* Handle null string condition */ }
適合コード (strncpy_s()
, C11 附属書K)
C11 附属書K のstrncpy_s()
関数は、コピー元の配列からコピー先の配列に最大 n
文字コピーする [ISO/IEC 9899:2011]。コピー元の配列から null 文字がコピーされない場合、コピー先配列の n
番目の位置が null 文字に設定され、結果の文字列は確実に null 終端される。
char *source; char a[NTBS_SIZE]; /* ... */ if (source) { errno_t err = strncpy_s(a, sizeof(a), source, 5); if (err != 0) { /* エラー処理 */ } } else { /* null 文字列条件の処理 */ }
リスク評価
型の安全性を徹底しなければ、プログラム内で型に関するエラーが発生する可能性がある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
API07-C |
中 |
低 |
中 |
P4 |
L3 |
関連するガイドライン
ISO/IEC TR 24772:2013 | 6.8 String Termination [CJM] |
ISO/IEC 9899:2011 | Annex K.3.7.1.4, "The strncpy_s Function" |
翻訳元
これは以下のページを翻訳したものです。
API07-C. Enforce type safety (revision 21)