CS.LOCRET.RET
関数によってローカル変数のアドレスが返されました
以前に解放されたメモリを使用すると、欠陥のインスタンス化とタイミングに応じて、有効なデータの破損から任意のコードの実行に至るまで、さまざまな悪影響を及ぼす可能性があります。データ破損が発生する可能性がある最も簡単な方法として、システムによる解放メモリの再利用があります。C# には、まだ参照が存在すればメモリを解放しないガベージコレクターが内部にありますが、そうした参照は安全でないブロックで発生する可能性があるため、解放後の使用はまれな状況となります。CS.LOCRET チェッカーファミリが検出するのは、安全でない関数が、ブロックのスコープ外で、ローカル変数のアドレスにアクセスできるようにし、ダングリングポインターや解放後の使用などの指摘を引き起こすようなインスタンスです。
CS.LOCRET.RET チェッカーは、関数が return ステートメント内の式を通じてローカル変数のアドレスを返す、インスタンスを検出します。
脆弱性とリスク
ローカル変数はスタックに割り当てられるため、関数がポインターを変数に返すとき、スタックアドレスが返されています。このアドレスは関数から戻った後は無効になります。このため、このアドレスにアクセスすると、アプリケーションが予期しない動作 (通常、プログラムクラッシュ) をする可能性があります。
解放後の使用エラーには、場合によっては重複する、次の 2 つの一般的な原因があります。
- エラー条件およびその他の例外的な状況。
- プログラムのどの部分がメモリ解放に関与しているかについての混乱。
脆弱コード例
using System.IO;
namespace Example
{
class Program
{
unsafe static int* aaa()
{
int *aux = stackalloc int[3];
return aux; //@ CS.LOCRET.RET
}
static void Main(string[] args)
{
unsafe {
int *a = aaa(); // 'a' points to freed memory
}
}
}
}
Klocwork は、9 行目で CS.LOCRET.RET の欠陥を報告します。そこでは、関数 'aaa' がローカル変数 'aux' のアドレスを返します。
関連チェッカー
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。