ELF64 / x86_64 and the start address of the memory mapping segment (for shared objects)

I wrote several programs and found out that when compiling to 64 bit, the memory mapping segment (where, for example, shared objects and shared memory are stored) is always somewhere around 7f9aca84a000-7fff88400000, but not quite exactly.

I would like to know if there is a fixed start address for this memory segment in the x86_64 architecture (ELF64) or what is the maximum and minimum range for this segment?

That is why I am asking this question. We are moving the system from Tru64 UNIX to Linux. This system used sophisticated fixed memory mapping for IPC Sys V shared memory, and it uses a chained list to move from structure to another within this segment. Given the size and complexity of this piece of code and the limited time that we have at hand, we are trying to find a reliable way to fix the beginning of shared memory (effectively using shmat with the specified address, with which you can attach a segment). With a 64-bit virtual address space so huge (48bit of effectively possible addresses) that choosing a "secure" fixed address is much simpler and less risky than on a 32-bit one.

+5
source share
3 answers

The x86-64 memory mapping scheme is defined in arch/x86/mm/mmap.c. As you can see, two strategies are used: top to bottom and bottom to top.

Top-down distribution by default. It starts with 128 MB below the maximum stack length (as determined by the riffit stack), is configured with a random offset, and then allocates subsequent mappings down in memory from there.

Highlighting the bottom is a reserve. It is used if:

  • Unlimited stack size
  • The process has a set ADDR_COMPAT_LAYOUT; or
  • vm.legacy_va_layout sysctl is nonzero.

, TASK_SIZE / 3, . TASK_SIZE x86-64 0x800000000000, 0x2AAAAAAAAAAA.

, 2 * TASK_SIZE / 3 - 0x500000000000.

+4

mmaped ?

. Linux ASLR ( ), , . . , , ASLR ( x86), PaX, exec-shield,...

, , MAP_FIXED, @Ethereal.

+4

(!), , . :

#include <stdio.h>
#include <sys/mman.h>
#include <stdint.h>

#define ADDRESS 0x700000000

int main(int argc, char *argv[]) {
    uint64_t *map = mmap((void *)ADDRESS, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

    map[0] = 64;

    printf("Value: %lu\n", map[0]);

    munmap(map, 4096);

    return 0;
}

I'm afraid I don’t have time to look at the source of the kernel at the moment, but I will definitely look later. I always wondered what was the answer to this question.,.

+3
source

All Articles