CERT.VA_START.TYPE
va_start() に渡される引数の型は、実装全体で、明確に定義された動作をする必要があります。具体的には、次を避けるべきです。
- 参照
- 配列
- 非自明なコンストラクターまたはデストラクターを伴うクラス
- プロトタイプのない関数への引数として、または可変個引数の関数への末尾の引数として渡されるときに、デフォルトの昇格を受けるいずれかの型
CERT.VA_START.TYPE チェッカーは、サポートされていないオブジェクト型が 2 番目の引数として va_start() に渡される場合にフラグを立てます。
脆弱性とリスク
サポートされていない型のオブジェクトを va_start() に 2 番目の引数として渡すと、未定義の動作を引き起こし、データ整合性違反を発生させる可能性があります。
軽減と防止
va_start() に渡される 2 番目の引数がサポートされている型であることを確認してください。
脆弱コード例 1
#include <cstdarg>
extern "C" void f(float a, ...){
va_list list;
va_start(list, a);
// ...
va_end(list);
}
この非準拠の例では、正しくない型が 2 番目の引数として va_start() に渡されるため、Klocwork は 5 行目で CERT.VA_START.TYPE の欠陥を報告します。これは、デフォルトの引数の昇格後、型「float」が「double」に変換され、未定義の動作を引き起こす可能性があるためです。
修正コード例
#include <cstdarg>
extern "C" void f(double a, ...){
va_list list;
va_start(list, a);
// ...
va_end(list);
}
脆弱なコード例 #2
#include <cstdarg>
#include <iostream>
extern "C" void f(int &a, ...){
va_list list;
va_start(list, a);
if (a) {
std::cout << a << ", " << va_arg(list, int);
a = 100; // Assign something to a for the caller
}
va_end(list);
}
この非準拠の例では、参照型が 2 番目の引数として va_start() に渡され、未定義の動作を引き起こす可能性があるため、Klocwork は 6 行目で CERT.VA_START.TYPE の欠陥を報告します。
修正コード例 #2
#include <cstdarg>
#include <iostream>
extern "C" void f(int *a, ...){
va_list list;
va_start(list, a);
if (a && *a) {
std::cout << a << ", " << va_arg(list, int);
*a = 100; // Assign something to *a for the caller
}
va_end(list);
}
上記のコードは、正しい型「double」が 2 番目の引数として va_start() に渡されるため、準拠しています。
脆弱なコード例 #3
#include <cstdarg>
#include <iostream>
#include <string>
extern "C" void f(std::string s, ...){
va_list list;
va_start(list, s);
std::cout << s << ", " << va_arg(list, int);
va_end(list
}
この非準拠の例では、非自明なコピーコンストラクターが 2 番目の引数として va_start() に渡され、未定義の動作を引き起こす可能性があるため、Klocwork は 7 行目で CERT.VA_START.TYPE の欠陥を報告します。
修正コード例 #3
#include <cstdarg>
#include <iostream>
extern "C" void f(const char *s, ...){
va_list list;
va_start(list, s);
std::cout << (s ? s : "") << ", " << va_arg(list, int);
va_end(list);
}
上記のコードは、std::string の代わりに const char* を渡し、それには明確に定義された実装があるため、準拠しています。