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
{
---
---
}
}
for ループに break 文を使用した条件付き終了があるため、Klocwork は欠陥を報告しなくなります。
修正コード例 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
{
---
---
}
}
ループは、resource_count 変数によって制御され、ループの条件として MAX_RESOURCES_TO_BE_CONSUMED と比較されるため、Klocwork は欠陥を報告しなくなります。
脆弱コード例 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;
}
-----
-----
}
}
}
}
制御されない while ループは break 文によって条件付きで停止するため、Klocwork は欠陥を報告しなくなります。
脆弱なコード例 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);
}
}
}
制御されない for ループは break 文によって条件付きで停止するため、Klocwork は欠陥を報告しなくなります。