6

次のコード行に Coverity バグがあります。

snprintf( tempStr, size, testStrings[testID], A2DtoV(testResults[testID].value),
A2DtoV(testResults[testID].min),A2DtoV(testResults[testID].max));

エラーは言う:

non_const_printf_format_string: "format string is not a string literal, 
potential security vulnerability if user controlled"

testStrings を const に変更しましたが、何もしませんでした:

static const char *testStrings[] = {"1", ... etc};

このエラーが実際に何を言っているのかについてのアイデアはありますか?

4

2 に答える 2

12

あなたのコードは問題ありません。

問題は、ユーザーが制御する文字列を printf フォーマット文字列として渡すと、セキュリティ バグが発生する可能性があることです。

例えば、printf(userName);

userName がユーザーによって提供される場合、ユーザーは "%s" を渡し、スタック上のランダムなアドレスでデータへのアクセスを開始する関数を取得できます。これにより、クラッシュが発生する可能性があります。printf は追加のパラメーターをスタックから取り出そうとするため、スタックが破損します。このようなサービス拒否攻撃はおそらく最良のケースです。printf を取得してスタック上の値をダンプすることで情報を開示できます。また、printf スタイルの関数を取得してスタック上の戻りアドレスを変更する方法さえあります。

文字列はユーザ​​ーによって制御されないため、このメッセージは無視しても問題ありません。典型的な修正は、私が与えた printf の例を に置き換えることですprintf("%s", userName);。これは、const 文字列にフォーマット文字列が含まれているように見えるため、あなたの場合には役に立たないようです。

ウィキペディアには、フォーマット文字列の脆弱性に関する詳細があります: http://en.wikipedia.org/wiki/Format_string_vulnerabilities

于 2009-03-10T18:40:24.720 に答える
2

アイデアは、の値をtestStrings[testID]何らかの方法で変更して、追加のフォーマット指定子を含めることができるということです。

パラメータの数がフォーマット指定子の数と一致するかどうかを確認する可能性がないためsnprintf()、スタックから次のアドレスを取得して次のフォーマット指定子の値として使用するだけで、奇妙なことが起こる可能性があります。

これは、フォーマット文字列攻撃として知られています。

于 2009-03-10T18:38:41.497 に答える