Linuxでプロセス単位にaslrのon/offを切り替える仕組みめも

gdb turns off ASLR « codeblogを見ていてpersonality(2)を使えば良いのか〜と知ったのでめもです。

tl;dr

personality(2)でADDR_NO_RANDOMIZEをセットすればoffにできる。

personality(2)

aslr以外にも設定可能な項目はいくつか有ります。設定されている内容を見るだけなら /proc/<pid>/personality を読んで調べることができます。

テストコード

とりあえずこんな感じのコードを。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/personality.h>

static void show_pointer_address(void)
{
    int n;

    printf("[*] local variable address is %p\n", &n);
}

static void show_current_persona(void)
{
    int persona = personality(0xffffffff);
    printf("[*]current setting is 0x%x\n", persona);
}

int main(int argc, char **argv)
{
    show_current_persona();

    if (argc == 2 && !strcmp(argv[1], "show")) {
        show_pointer_address();
        return 0;
    } else if (argc == 2 && !strcmp(argv[1], "no_aslr")) {
        printf("[*]set aslr off\n");
        personality(ADDR_NO_RANDOMIZE);
    }

    pid_t pid = fork();

    if (pid < 0) {
        perror("fork");
        exit(-1);
    }

    if (!pid) {
        execl(argv[0], argv[0], "show",  NULL);
    } else {
        int status;
        waitpid(pid, &status, 0);
    }

    return 0;
}

動かしてみる

aslrを無効にしない場合

masami@saga:~/codes/personality_test$ for((i=0;i<10;i++)); do ./a.out ; done | grep local
[*] local variable address is 0x7fffa4082aac
[*] local variable address is 0x7ffc06ed6a4c
[*] local variable address is 0x7fff8bc1fbac
[*] local variable address is 0x7ffdd78eb9dc
[*] local variable address is 0x7ffe2c88ed3c
[*] local variable address is 0x7ffd32bde89c
[*] local variable address is 0x7fffa323205c
[*] local variable address is 0x7ffd22dc153c
[*] local variable address is 0x7ffe5613520c
[*] local variable address is 0x7ffdee4e8dec

aslrを無効にした場合

masami@saga:~/codes/personality_test$ for((i=0;i<10;i++)); do ./a.out no_aslr; done | grep local
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc
[*] local variable address is 0x7fffffffd2dc