5

Address Space Layout Randomization (ALSR) により、別のプロセスから fork されたプロセスは、 を呼び出したときに異なるアドレスが返されると予想されますmmap。しかし、私が知ったように、そうではありませんでした。そのために以下のテストプログラムを作成しました。によって返されるすべてのアドレスはmalloc、親と子でまったく同じです。mallocfor cl1cl2pl1pl2mmapは大きなブロックであるため、内部で使用されることに注意してください。

それで、私の質問は、mmapALSR が存在する場合でも異なるアドレスを返さないのはなぜですか。おそらく、ここでのランダム化のシードは、元のプロセスとフォークされたプロセスで同じであるためです。それとも他に理由がありますか?

int main()
{
  pid = fork();

  if (pid == 0)                // child
  {
    void * c1 = malloc( 4096 );
    void * c2 = malloc( 4096 );

    void * cl1 = malloc( (long)512e3 ); // internally uses mmap
    void * cl2 = malloc( (long)512e3 ); // internally uses mmap

    printf( "c1 = %p, c2 = %p, cl1 = %p, cl2 = %p!\n", c1, c2, cl1, cl2 );
  }
  else
  {
    void * p1 = malloc( 4096 );
    void * p2 = malloc( 4096 );

    void * pl1 = malloc( (long)512e3 ); // internally uses mmap
    void * pl2 = malloc( (long)512e3 ); // internally uses mmap

    printf( "p1 = %p, p2 = %p, pl1 = %p, pl2 = %p!\n", p1, p2, pl1, pl2 );
  }

  return 0;
}
4

2 に答える 2

6

ASLR は主に、ユーザー空間アドレス空間の最上部からスタックまでの距離と、スタック予約空間の最下部から最初の空間までの距離をランダム化しますmmap(これはおそらく動的リンカーのマッピングです)。それ以上のランダム化は、仮想メモリ空​​間に深刻な断片化の影響を与えるため、大きなmmaps を作成する必要があるプログラム (たとえば、32 ビット マシンでの 1 ~ 2 GB のマッピング) が機能しなくなります。

一部の Linux ディストリビューションでは、 によって返されるアドレスに対してより多くのランダム化を実行するパッチが適用されたカーネルが出荷されているのを見てきましたmmap。それらのいくつかは、スタックが拡張するために予約されたスペースと重複するマッピングを提供し、スタックが成長すると、マッピングを破壊します(結果として、非ランダムなアドレス割り当てが引き起こす可能性のあるものよりもはるかに大きなギャップのあるセキュリティホールが発生します) . これらのハッキングには近づかないでください。

于 2012-02-28T16:18:04.737 に答える
4

子のアドレス空間を再ランダム化することはできません - すべてのポインターを修正する必要があり、それは技術的に不可能です (ランタイム環境はデータのどの部分がポインターであるかさえ知りません)。

したがって、表示されている結果は予想どおりです。フォークの子には、仮想アドレス レイアウトを含め、フォーク時に親アドレス空間の正確なコピーがあります。

exec*新しいアドレス空間レイアウトを取得するには、呼び出しが必要です。

$ cat t.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%p\n", malloc((long)512e3));
    if ((argc > 1) && fork()) {
        execl("./a.out", "./a.out", NULL);
    }
    return 0;
}
$ gcc -Wall t.c
$ ./a.out 1
0x7f5bf6962010
0x7f3483044010
$ ./a.out 1
0x7f1ce7462010
0x7feb2adc2010

(そして/proc/sys/kernel/randomize_va_spaceもゼロでないことを確認してください。)

于 2012-02-28T16:16:12.203 に答える