サンドボックスの信頼できる部分に次の疑似コードがあり、信頼できないコードがmprotect()
とmmap()
とptrace()
を直接呼び出せないようにしているとします(サンドボックス化されたメモリからマルチテキストにアクセスできません)…
_//src and dest are user controlled but must be valid.
TrustedPart_for_safe_jit(void * mutext, uint8_t *src,uint8_t *dest, uint32_t size) // in the current case, *dest targets a PROT_NONE memory region
{
MutexLock(mutext);
ValidateOpcodesOrCrash(src,size); // uses calls to mmap on size internally. Contains many different loops and use several 10k thousands lines of codes in the trusted part of the sandbox : this is the longest part. Please also note that src is write protected while being in this function.
unwriteprotect(dest,size); // calls many sandbox’s internal functions
SafeMemcpy(src,dest,size); // THIS IS the function which contains the race condition
asm("mfence");
unEXECprotect(dest,size); // involve write protecting as well as allowing reading
MutexUnlock(mutext);
}
SafeMemcpy(uint8_t *src,uint8_t *dest, uint32_t size) // the data to be copied cannot exceed 128Mb
{
if(!CheckUserTargetPointToValidMemroyRange(dest,size) {
uint8_t *src_ptr=src;
uint8_t *dest_ptr=dest;
uint8_t *end_ptr=des+size;
while (dest_ptr < end_ptr) { // that loop should execute very fast
*(uint32_t *) dest_ptr = *(uint32_t *) src_ptr;
dest_ptr += 4;
src_ptr += 4;
}
}
}
_
その部分は、信頼できないコードがtoコンパイルを使用できるようにする責任があります。
要点は、信頼されていないスレッドが中断されていないことです。
ご存知のように、2つのスレッドが同じ宛先でmemcpy()
を使用すると、ランダムなデータが生成されます。その場合、そのようなデータには_int 0x80
_のような命令が含まれる可能性があるため、サンドボックスをエスケープすることができます。
これまでに考えたこと:
それで、memcpy競合状態のタイミングウィンドウを計画することは可能ですか?
ここに表示される内容に基づいて、ValidateOpcodesOrCrashがメモリのその部分のチェックを終了した後、SafeMemcpyが開始する前に* srcを変更できます。
ValidateOpcodesOrCrashがどのように実装されているかはわかりませんが、[src,src+size]
をループして不正な命令を探すだけだとすると、かなりのTrustedPart_for_safe_jitラージsize
を使用して呼び出すことができます。のCPUサイクルを確認し、ValidateOpcodesOrCrashがチェックを終了したと思われる*src
の上書きを開始します。 ValidateOpcodesOrCrashがより複雑な処理を行う場合、ValidateOpcodesOrCrashがチェックする最速かつ最速の命令シーケンスを特定し、最速の命令を最前部に配置し、最も遅い命令の多くを最後まで使用できます。 srcの上書きを開始する前に、ValidateOpcodesOrCrashが完了するのを待つ必要はおそらくないでしょう。
(免責事項:私はセキュリティの専門家ではありません。Cについてある程度の知識を持つ学生のみです)
これは、少なくともクラッシュを引き起こすために悪用される可能性が高いと思います。バグを修正するには、次のいずれかを行う必要があります。
dest
が書き込み可能である間、すべての信頼できないスレッドを一時停止します。TrustedPart_for_safe_jit
return 新しく割り当てられた実行可能メモリ(信頼できないコードがポインタとして任意のマシンのアドレスを不正に使用することは許可されていないと思います)。つまり、ミューテックスを使用する代わりに、世界を止める必要があります。