CS.RESOURCE.LOOP

循环内的对象分配

每当在没有显式退出条件的循环体内创建任何对象时,此检查器都会报告缺陷。如果在循环体的末尾没有对对象的引用,则可能会用垃圾回收器快速处置一些资源,但无法保证这种处置的时机。此外,某些已分配资源的使用寿命可能会延长,这可能导致过多的资源消耗,从而导致资源耗尽或程序失败。

漏洞与风险

该软件未能正确控制有限资源的分配和维护,从而使参与者能够影响所消耗的资源数量,最终可能导致可用资源耗尽。有限资源包括内存、文件系统存储、数据库连接池条目和 CPU。如果攻击者可以触发这些有限资源的分配,但资源的数量或大小又不受控制,则攻击者可以发起拒绝服务攻击,从而消耗掉所有可用资源。拒绝服务攻击会阻止有效用户访问软件,也可能会对周围环境产生影响。

漏洞代码示例 1

复制
   namespace ResourceLoop
   {
     class TestResourceLoop
     {
       public static void ResourceLoopExample1()
       {
          for (;;){
            Test obj = new Test();         // CS.RESOURCE.LOOP
            -----
           -----
         }
       } 
    }
    class Test
    {
     ---
     ---
     }
  }

在以上示例中,攻击者可以触发 ResourceLoopExample1 方法,其中 Class Test 可以具有不受控制的资源分配。可用资源可能会被不受控制的资源消耗所消耗。

Klocwork 报告第 8 行出现 CS.RESOURCE.LOOP 缺陷,这表示“类型对象 Test 已在潜在的无限循环内得到分配,这可能导致不受控制的有限资源消耗”。

修正代码示例 1a

复制
   namespace ResourceLoop
   {
     class TestResourceLoop
     {
       public static void ResourceLoopExample1()
       {
               resource_count = 0;
               for (;;){
           Test obj = new Test(); 
          ++resource_count;
          if (resource_count > MAX_RESOURCES_TO_BE_CONSUMED) {
            break;
          }
          -----
        }
      } 
    }
    class Test
    {
      ---
      ---
    }
  }

Klocwork 不再报告缺陷,因为 for 循环通过使用 break 语句具备条件退出。

修正代码示例 1b

复制
   namespace ResourceLoop
   {
     class TestResourceLoop
     {
       public static void ResourceLoopExample1()
       {
               resource_count = 0;
               for (; resource_count > MAX_RESOURCES_TO_BE_CONSUMED; resource_count++){
           Test obj = new Test
          -----
        }
      } 
    }
    class Test
    {
      ---
      ---
    }
  }

Klocwork 不再报告缺陷,因为该循环由 resource_count 变量控制,并与 MAX_RESOURCES_TO_BE_CONSUMED 进行比较,以此作为循环的条件。

漏洞代码示例 2

复制
   namespace ResourceLoop
   {
     class TestResourceLoop
     {
       public static void ResourceLoopExample2()
       {
               while(true){
           int[] obj = new int[SOME_NUMBER];         // CS.RESOURCE.LOOP
           -----
          -----
        }
      } 
    }
  }

在以上示例中,攻击者可以触发 ResourceLoopExample2 方法,其中 Class Test 可以具有不受控制的资源分配。可用资源可能会被不受控制的数组对象创建所消耗。

Klocwork 报告第 8 行出现 CS.RESOURCE.LOOP 缺陷,这表示“类型对象 int[ ] 已在潜在的无限循环内得到分配,这可能导致不受控制的有限资源消耗”。

修正代码示例 2

复制
   namespace ResourceLoop
   {
     class TestResourceLoop
     {
       public static void ResourceLoopExample2()
       {
               while(true){
           int[] obj = new int[SOME_NUMBER]; 
           number_of_resources += obj.length;
          if (number_of_resources > MAX_RESOURCES_TO_BE_CONSUMED){
            break;
          }
  
          -----
          -----
        }
      } 
    }
  }

Klocwork 不再报告缺陷,因为不受控制的 while 循环已被 break 语句有条件地停止。

漏洞代码示例 3

复制
   namespace ResourceLoop
   {
     class TestResourceLoop
     {
       public static void ResourceLoopExample3()
       {
               do {
           Test obj = new { X = 1, Y = 1 };         // CS.RESOURCE.LOOP
           -----
          -----
        } while(true);
      } 
    }
    class Test
    {
      ---
      ---
    }
  }

在以上示例中,攻击者可以触发 ResourceLoopExample1 方法,其中 Class Test 可以具有不受控制的资源分配。可用资源可能会被不受控制的资源消耗所消耗。

Klocwork 报告第 8 行出现 CS.RESOURCE.LOOP 缺陷,这表示“类型对象 <anonymous type> 已在潜在的无限循环内得到分配,这可能导致不受控制的有限资源消耗”。

修正代码示例 3

复制
   namespace ResourceLoop
   {
     class TestResourceLoop
     {
       public static void ResourceLoopExample3()
       {
               do{
           Test obj = new { X = 1, Y = 1 }; 
           number_of_resources += 1;
          if (number_of_resources > MAX_RESOURCES_TO_BE_CONSUMED){
              break;
          }
  
          -----
          -----
        }while(true);
      } 
    }
  }

Klocwork 不再报告缺陷,因为不受控制的 for 循环已被 break 语句有条件地停止。