割り当てサイズの計算での整数オーバーフロー

割り当てサイズの計算での整数オーバーフロー

説明

長さに対する算術演算の結果をそのまま割り当てサイズに使うと、整数オーバーフローやラップアラウンドが起こる可能性があります。

想定される影響

  • 想定より小さいバッファーが作られたり、実行時にパニックが発生したりするおそれがあります。
  • 入力サイズを悪用され、サービス拒否につながる可能性があります。

対処方法

  • 演算の前に、入力の長さと乗算の各オペランドに上限を設けてください。
  • 計算結果が型の最大値を超えないことを確認してください。

例

変更前

go
func allocateImage(width, height int) []byte {
    return make([]byte, width*height)
}

変更後

go
func allocateImage(width, height int) []byte {
    const maxBufferBytes = 64 * 1024 * 1024
    if width <= 0 || height <= 0 || width > maxBufferBytes/height {
        return nil
    }
    size := width * height
    return make([]byte, size)
}

解説:

  • 変更前: 入力された幅と高さを検証せずに掛け合わせるため、割り当て前にオーバーフローやラップアラウンドが起こる可能性があります。
  • 変更後: 最初に0以下の値を拒否して除算のエラーを防ぎ、乗算前にサービスのバッファー上限を確認します。上限が int の範囲内なので、検証を通った乗算はオーバーフローしません。整数の範囲内でも過大な割り当ては拒否します。

参考資料