Reputation: 387
I have this structure:
struct Books {
char title[50];
char author[50];
};
Let's say that I know that if I pass arg1
to the program, in some part of the code, it adds some chars in the direction $title+52
, so the author
value is overwritten (buffer overflow).
Now I add ASLR to my binary. By this way, some directions are random, so I think the buffer overflow that I described before could not be possible.
Is this true? Or even if I add ASLR the directions of struct members are together and buffer overflow could be possible?
Upvotes: 3
Views: 1634
Reputation: 69276
I think you are misunderstanding the effects of ASLR (Address Space Layout Randomization): ASLR randomly arranges the positions of different virtual memory areas of a process (executable, stack, heap, data, libraries, etc) to be different in every execution. It does not change the relative position of elements in the same virtual memory area.
Take for example the following simple program:
int main(void) {
struct {
char a[10];
char b[10];
} myvar;
printf("a: %p\n", &myvar.a);
printf("b: %p\n", &myvar.b);
return 0;
}
Here's the program's virtual memory with ASLR disabled:
0x555555554000 0x555555555000 r-xp 1000 0 /home/marco/test/test [executable segment]
0x555555754000 0x555555755000 r--p 1000 0 /home/marco/test/test [read only data]
0x555555755000 0x555555756000 rw-p 1000 1000 /home/marco/test/test [bss (global variables)]
0x7ffffffde000 0x7ffffffff000 rw-p 21000 0 [stack] <-- myvar is here
Output (ASLR disabled):
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
And here's the same program with ASLR enabled:
0x559fefcbe000 0x559fefcbf000 r-xp 1000 0 /home/marco/test/test [executable segment]
0x559fefebe000 0x559fefebf000 r--p 1000 0 /home/marco/test/test [read only data]
0x559fefebf000 0x559fefec0000 rw-p 1000 1000 /home/marco/test/test [bss (global variables)]
0x7ffe3bb5e000 0x7ffe3bb7f000 rw-p 21000 0 [stack] <-- myvar is here
Output (ASLR enabled):
$ ./test
a: 0x7ffe3bb5e080
b: 0x7ffe3bb5e08a
$ ./test
a: 0x7ff4abdeea80
b: 0x7ff4abdeea8a
$ ./test
a: 0x7efa6b8fa080
b: 0x7efa6b8fa08a
Your variable is still going to be inside a certain contiguous block of virtual memory, and the relative position of the fields will not change at all. Contiguous arrays will still be contiguous using ASLR: they will just start at a different position in memory.
Since struct
fields are by standard contiguous in memory (and follow their declaration order), this means that buffer overflow will still be a potential problem, even when using ASLR.
Upvotes: 2
Reputation: 223689
The specific overflow you mentioned is still possible.
With the exception of bitfields, the fields of a structure follow one another in order in memory (with some possible padding in between). This is detailed in section 6.7.2.1p15 of the C standard:
Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
So in this case the author
field will always follow the title
field, regardless of what specific address an object of type struct Books
is located at. The only possible difference could be the amount of padding, but unless you add or remove fields in the struct this probably won't change.
Upvotes: 5
Reputation: 133849
ASLR does not affect stuff that is compile-time. The compiler chooses the layout of the structure at the time of compilation and this is hardcoded in the resulting object code.
Furthermore, the C standard requires that successive struct members are laid out in memory in the order they appear in the struct definition (with unspecified padding in between members, but this too is fixed at the compilation time)
Upvotes: 2