信頼できないメモリアドレスが与えられた場合、それが有効でアクセス可能なメモリを指しているかどうかをLinuxでテストする方法はありますか?
たとえば、マッハでは、vm_read_overwrite()を使用して、指定された場所からデータをコピーしようとすることができます。アドレスが無効またはアクセスできない場合、プロセスをクラッシュさせるのではなく、エラーコードを返します。
write
そのメモリから(/dev/null
たとえば(編集:/dev/null
期待どおりに機能しない可能性があるため、パイプを使用))、EFAULT
アドレスにアクセスできない場合はエラーが発生します。
書き込み可能である場合、コンテンツを破棄せずに書き込み可能メモリをテストする方法がわかりません。
これはTOCTOUの典型的なケースです。ある時点でメモリが書き込み可能であることを確認し、後で書き込みを試みます。何らかの理由で(たとえば、アプリケーションがメモリの割り当てを解除したため)、メモリにアクセスできなくなります。
これを実際に行うための有効な方法は1つだけです。つまり、実際に使用する必要があるときに、書き込みによって発生する障害をトラップします。
もちろん、トリックを使用してメモリが「書き込み可能」かどうかを判断することはできますが、実際に書き込み可能であることを確認する方法はありません。
実際に何をしようとしているのかをもう少し詳しく説明したいと思うかもしれません。もっと具体的にすれば、もっと良いアイデアが得られるかもしれません。
msyncを試すことができます:
int page_size = getpagesize();
void *aligned = (void *)((uintptr_t)p & ~(page_size - 1));
if (msync(aligned, page_size, MS_ASYNC) == -1 && errno == ENOMEM) {
// Non-accessibe
}
ただし、この関数は低速である可能性があるため、パフォーマンスが重要な状況では使用しないでください。