web-dev-qa-db-ja.com

Linuxでのカナリアワードのサイズは通常どれくらいですか?

カナリーワード は、バッファーオーバーフローを検出して対応する方法として、プログラム内のバッファー(スタックなど)と制御データの間の境界に配置される一連のビットです。

Linuxでは、これらのカナリアは通常何ビット長ですか?

38
MR.X_XD

やってみよう!これは非常に単純なサンプルプログラムです。

int test(int a)
{
    return a;
}

GCCでコンパイルし、アセンブリ段階でコンパイルをインターセプトします。 (-Sフラグがこれを行います。)アセンブリファイルの名前を変更して(上書きされないように)、再度コンパイルします。今回は-fstack-protector-allフラグと-mstack-protector-guard=globalフラグも追加します。最初のフラグはすべての関数のスタックカナリアを有効にし、2番目のフラグはスレッドローカルのカナリアではなくグローバルカナリアを選択します。 (スレッドローカルのデフォルトは、実際にはおそらくより有用ですが、グローバルバージョンのアセンブリは理解しやすいです。)

生成された2つのアセンブリファイルを比較すると、次の追加が見つかります(コメントは私のものです)。

        movl %edi, -20(%rbp)                 ; save function parameter onto stack (unrelated to canary)
        movq __stack_chk_guard(%rip), %rax   ; load magic value into RAX register
        movq %rax, -8(%rbp)                  ; save RAX register onto stack (place the canary)
        movl -20(%rbp), %eax                 ; load function parameter into EAX register for return (unrelated to canary)
        movq -8(%rbp), %rcx                  ; load canary value into RCX register
        movq __stack_chk_guard(%rip), %rdx   ; load magic value into RDX register
        cmpq %rdx, %rcx                      ; compare canary value to expected value
        je .L3                               ; if they are the same, jump to label .L3 (continue)
        call __stack_chk_fail                ; otherwise (stack corruption detected), call the handler
.L3:
        leave

カナリアはすべて64ビット幅のRAX、RCX、RDXレジスタで処理されることがわかります。 (それらの32ビット版はEAX、EBX、EDXという名前になります。16ビットバージョンはAX、BX、CXと呼ばれます。8ビットバリアントのAL、BL、CLです。)別の手がかりは、カナリア(MOVQおよびCMPQ)には、64ビット命令を識別する「Q」サフィックスがあります。 (32ビット命令には「L」、16ビット命令には「W」、8ビットバージョンには「B」というサフィックスが付いています)。

したがって、カナリアは64ビット値であり、64ビットアーキテクチャ(私の場合はx86_64 GNU/Linux)で意味があると結論付けます。私にとって最も理にかなっているので、ネイティブのWordサイズが常に使用されることを期待しています。マシンで同じ実験を試して、何が得られるかを確認できます。

59
5gon12eder

私がこのページで読むことができるように: Stack Smashing Protector

スタックカナリアはネイティブのWordサイズであり、ランダムに選択した場合、攻撃者は2 ^ 32または2 ^ 64の組み合わせの中から適切な値を推測する必要があります

24

使用されるビット数は、プロセッサのワードサイズと等しくなければなりません。したがって、32ビットプロセッサを使用している場合、そのワードサイズは32なので、カナリアワードは32ビット長です。

2
async3