CS.RESOURCE.LOOP

Object Allocation inside a loop

This checker reports a defect whenever any object is created inside the body of a loop that has no explicit exit condition. While some resources might be quickly disposed of with the garbage collector if no references to the object remain at the end of the loop body, the timing of such disposal is not guaranteed. Moreover, some allocated resources can have an increased lifespan that can result in excessive resource consumption, potentially leading to the exhaustion or resources and program failure.

Vulnerability and risk

The software does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the potential exhaustion of available resources. Limited resources include memory, file system storage, database connection pool entries, and CPU. If an attacker can trigger the allocation of these limited resources, but the number or size of the resources is not controlled, then the attacker could initiate a Denial of Service attack that consumes all available resources. Denial of Service attacks prevent valid users from accessing the software, and it can potentially have an impact on the surrounding environment.

Vulnerable code example 1

1   namespace ResourceLoop
2   {
3     class TestResourceLoop
4     {
5       public static void ResourceLoopExample1()
6       {
7          for (;;){
8            Test obj = new Test();         // CS.RESOURCE.LOOP
9            -----
10           -----
11         }
12       } 
13    }
14    class Test
15    {
16     ---
17     ---
18     }
19  }

In the above example, the attacker can trigger the ResourceLoopExample1 method where the Class Test can have an uncontrolled resource allocation. The available resources can be consumed by the uncontrolled resource consumption.

Klocwork reports a CS.RESOURCE.LOOP defect at line 8, indicating that “An object of type 'Test' is allocated inside a potentially infinite loop that can cause uncontrolled limited resource consumption”.

Fixed code example 1a

1   namespace ResourceLoop
2   {
3     class TestResourceLoop
4     {
5       public static void ResourceLoopExample1()
6       {
7               resource_count = 0;
8               for (;;){
9           Test obj = new Test(); 
10          ++resource_count;
11          if (resource_count > MAX_RESOURCES_TO_BE_CONSUMED) {
12            break;
13          }
14          -----
15        }
16      } 
17    }
18    class Test
19    {
20      ---
21      ---
22    }
23  }

Klocwork no longer reports a defect, since the for loop has a conditional exit by using the break statement.

Fixed code example 1b

1   namespace ResourceLoop
2   {
3     class TestResourceLoop
4     {
5       public static void ResourceLoopExample1()
6       {
7               resource_count = 0;
8               for (; resource_count > MAX_RESOURCES_TO_BE_CONSUMED; resource_count++){
9           Test obj = new Test
10          -----
11        }
12      } 
13    }
14    class Test
15    {
16      ---
17      ---
18    }
19  }

Klocwork no longer reports a defect, since the loop is controlled by the resource_count variable and compared with MAX_RESOURCES_TO_BE_CONSUMED as a condition of the loop.

Vulnerable code example 2

1   namespace ResourceLoop
2   {
3     class TestResourceLoop
4     {
5       public static void ResourceLoopExample2()
6       {
7               while(true){
8           int[] obj = new int[SOME_NUMBER];         // CS.RESOURCE.LOOP
9           -----
10          -----
11        }
12      } 
13    }
14  }

In the above example, an attacker can trigger the ResourceLoopExample2 method where the Class Test can have an uncontrolled resource allocation. The available resources can be consumed by the uncontrolled creation of array objects.

Klocwork reports a CS.RESOURCE.LOOP defect at line 8, indicating that “An object of type 'int[ ]' is allocated inside a potentially infinite loop that can cause uncontrolled limited resource consumption”.

Fixed code example 2

1   namespace ResourceLoop
2   {
3     class TestResourceLoop
4     {
5       public static void ResourceLoopExample2()
6       {
7               while(true){
8           int[] obj = new int[SOME_NUMBER]; 
9           number_of_resources += obj.length;
10          if (number_of_resources > MAX_RESOURCES_TO_BE_CONSUMED){
11            break;
12          }
13  
14          -----
15          -----
16        }
17      } 
18    }
19  }

Klocwork no longer reports a defect, since the uncontrolled while loop has been conditionally stopped by the break statement.

Vulnerable code example 3

1   namespace ResourceLoop
2   {
3     class TestResourceLoop
4     {
5       public static void ResourceLoopExample3()
6       {
7               do {
8           Test obj = new { X = 1, Y = 1 };         // CS.RESOURCE.LOOP
9           -----
10          -----
11        } while(true);
12      } 
13    }
14    class Test
15    {
16      ---
17      ---
18    }
19  }

In the above example, an attacker can trigger the ResourceLoopExample1 method where the Class Test can have an uncontrolled resource allocation. The available resources can be consumed by the uncontrolled resource consumption.

Klocwork reports a CS.RESOURCE.LOOP defect at line 8, indicating that “An object of type '<anonymous type>' is allocated inside a potentially infinite loop that can cause uncontrolled limited resource consumption”.

Fixed code example 3

1   namespace ResourceLoop
2   {
3     class TestResourceLoop
4     {
5       public static void ResourceLoopExample3()
6       {
7               do{
8           Test obj = new { X = 1, Y = 1 }; 
9           number_of_resources += 1;
10          if (number_of_resources > MAX_RESOURCES_TO_BE_CONSUMED){
11              break;
12          }
13  
14          -----
15          -----
16        }while(true);
17      } 
18    }
19  }

Klocwork no longer reports a defect, since the uncontrolled for loop has been conditionally stopped by the break statement.