脆弱性クイズ

過去の日報を読み返していたら、自分のメモにこんなものを発見した。:

//脆弱性クイズ! -- 以下のコードの問題点と、改善案を述べよ (10点)
void quiz(char c) {
  char buffer[4];
  sprintf_s(buffer, "%3.3o", c);
  // ... (snip) ...
}

…ぱっと見て、すぐに答えられなかった。

答え

printf ファミリーの関数に渡した文字型変数 c は int に整数拡張されるため、 127 を超える値を持つ文字を渡したときに (負の値と解釈され)、バッファーオーバーフロー (BOF) することがある。
ただし sprintf_s を使っていることから、パラメーター検証でひっかかり、呼び出されるハンドラーによって BOF が抑制されるかもしれない。
さらに細かいことを言うと、解釈系によっては文字型変数を符号なしとして扱うものがあるため、この場合は問題は起きない。

ただし書きがいっぱいつくあたり、悪い設問だなあ…。

改善案は c を符号なしとしてキャストすること。(としたかったんだろうな):

void quiz(char c) {
  char buffer[4];
  sprintf_s(buffer, "%3.3o", (unsigned char)c);
  // ... (snip) ...
}