RABV.CHECK

配列のサイズを超える配列値へのアクセス

チェッカーは、配列境界内にあるかどうかについてインデックスがチェックされる前に、配列にアクセスするケースを探します。

脆弱性とリスク

配列が配列のサイズを超えるインデックスによってアクセスされた場合、データが破壊され、誤動作/クラッシュが発生する場合があります。

脆弱コード例 1

コピー
  // some function returning an index
  int get_index();
  
  void main() {
      const int SIZE = 10;
  
      int arr[SIZE];
      int index = get_index();
  
      arr[index] = 0;
  
      if (index >= SIZE) {
          return;
      }
 }

Klocwork は、12 行目の有効性についてインデックスがチェックされる前に、インデックスが配列にアクセスするために使用されることを示す 10 行目について欠陥を報告します。

修正コード例 1

コピー
  // some function returning an index
  int get_index();
  
  void main() {
      const int SIZE = 10;
  
      int arr[SIZE];
      int index = get_index();
  
     if (index >= SIZE) {
         return;
     }
 
     arr[index] = 0;
 }

前のスニペットからの問題が修正されました。これにより、インデックスが配列へのアクセスのために使用される前にそのインデックスがチェックされます。

脆弱コード例 2

コピー
  int get_index();
  
  void set(int* arr, int index) {
      arr[index] = 0;
  }
  
  void main() {
      int SIZE = 10;
      int arr[SIZE];
     int index = get_index();
     
     set(arr, index);
    
     if (index >= SIZE) {
         return;
     }
 }

例 1 と似ていますが、しかしこの場合、配列は同じ関数「main」内でアクセスされずに、1 つのパラメーターとして別の関数「set」に渡されます。Klocwork は、14 行目の有効性についてインデックスがチェックされる前に、インデックスが関数「set」内で配列にアクセスするために使用されることを示す 12 行目について欠陥を報告します。

修正コード例 2

コピー
  int get_index();
  
  void set(int* arr, int index) {
      arr[index] = 0;
  }
  
  void main() {
      int SIZE = 10;
      int arr[SIZE];
     int index = get_index();
     
     if (index >= SIZE) {
         return;
     } 
         
     set(arr, index);    
 }

この欠陥も同じ方法で修正されます。これにより、インデックスは、16 行目の関数「set」に渡される前に 12 行目の有効性についてチェックされます。

関連チェッカー

セキュリティトレーニング

Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。