Search code examples
clinuxubuntuaslr

(ubuntu) ASLR - clear the mess, weird result


Hi I'm using Ubuntu and just turned off my ASLR to check 2 files(dumb.c and dumber.c)

dumb is creating a file and enter it variable address

dumber is reading it and printing I have a problem to understand the reason why in some computers it prints 16 and others 32767

dumb.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int i = 7;
    int j = 12;
    int k = 15;
    int *p = &j;

    FILE *fp;

    if(0 == (fp = fopen("dumb.txt", "w")))
    {
        printf("well, that didn\'t work!\n");
        return -1;
    }

    fprintf(fp, "%p\n", (void*)p);
    printf("Address from Dumb: %p, value: %d\n", (void *)p, *p);

    if(fclose(fp))
    {
        printf("oh well.");
        return -1;
    }

    sleep(300);

    return EXIT_SUCCESS;
}

dumber.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int i = 8;
    int j = 16;
    int k = 32;
    int *p = &j;

    FILE *fp;

    if(0 == (fp = fopen("dumb.txt", "r")))
    {
        printf("well, that didn\'t work!\n");
        return -1;
    }

    fscanf(fp, "%p\n", &p);

    if(fclose(fp))
    {
        printf("oh well.");
        return -1;
    }

    printf("\nDumber Address: %p\n", (void *)p);
    printf("p points to: %d\n", *p);

    return EXIT_SUCCESS;
}

Solution

  • At dumber.c you have:

    fscanf(fp, "%p\n", &p); /* getting address dumb process put there */

    Then you have:

    printf("p points to: %d\n", *p); /* reading memory content at that address */

    So in dumber process you read the address that dumb process put there, and from this point p does not point to j.

    Now in general, since those two mains are different processes, the content of memory address dumber sees will most likely be different than the value at the same address for dumb process, regardless of ASLR. That's just how processes work (I assume those processes runs in Linux\Windows\Mac), they are loaded to different physical addresses, with different virtual and physical address mapping, and also you have no idea in dumber process whether this address points to a valid address.

    Now, what happens here is when you run with ASLR, process address space (virtual addresses process uses) is certainly different between the two processes. Without ASLR process address space are same for all processes, at any case the physical addresses are likely to be different. Since the stack usage is same for both processes, dumb process writes the offset (the virtual address) of j to the file and dumber processes reads this offset, and since dumb process has it's j at same offset as dumber process, you will access dumber's j. With ASLR the address dumber sees was a valid address for dumb process but most likely not a valid one for dumber (probably no mapping for this address for dumber)

    You can verify it by changing the position of j in one of the processes, do that and you will never see 16 printed as the value at address pointed by j in dumber process.