Начало стека в Linux - PullRequest
       3

Начало стека в Linux

0 голосов
/ 06 февраля 2019

Я думал, что могу получить начало моего стека процессов, взяв адрес переменной в main и округлив до границы страницы (учитывая, что мой стек уменьшается).

Я сравнил это сГраница сообщается /proc/self/maps, и она всегда отключена на 1, 2 или 3 страницы (4096 байт на страницу), но не с другим смещением.Разница меняется с каждым прогоном, и эта программа на C, используемая в следующем (грязном, не минималистичном) конвейере, демонстрирует разницу.

stacksz.c:

#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#define CAT "cat /proc/XXXXXXXXXXX/maps"
#define CATP "cat /proc/%ld/maps"
#define MASK ((sizeof(char)<<12)-1)

int main()
{
    uintptr_t  top = (uintptr_t)&top + MASK & ~MASK;

    char cat[sizeof CAT];
    sprintf(cat,CATP,(long)getpid());
    if(system(cat)) return 1;

    printf(" %lx stack\n", top);
    return 0;
}

bash pipe:

gcc stacksz.c && echo "$(( $(./a.out |grep stack |tr '-' ' ' |cut -d' ' -f2 |sed 's/^/0x/'|tr '\n' -|sed 's/-$//') ))"

Мне любопытно, может кто-нибудь объяснить это явление.Машина Linux precision 4.15.0-43-generic #46-Ubuntu SMP x86_64.`(Я получил следующее распределение смещения за 1000 прогонов:

4096 195
8192 490
12288 315

).

1 Ответ

0 голосов
/ 06 февраля 2019

ASLR сначала полностью рандомизирует расположение стека в виртуальной памяти.Но он делает больше: он также рандомизирует указатель стека относительно вершины отображения стека!

Из исходного кода linux:

unsigned long arch_align_stack(unsigned long sp)
{
        if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
                sp -= get_random_int() % 8192;
        return sp & ~0xf;
}

Здесь, если ASLR активен, стекуказатель уменьшается на 0-8192 байта, а затем выравнивается на 16 байтов.Это объясняет переменное смещение 1-3 страницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...