Last week Data can be allocated on the stack or on the heap (aka - - PowerPoint PPT Presentation

last week
SMART_READER_LITE
LIVE PREVIEW

Last week Data can be allocated on the stack or on the heap (aka - - PowerPoint PPT Presentation

Last week Data can be allocated on the stack or on the heap (aka dynamic memory) or on the heap (aka dynamic memory) Data on the stack is allocated automatically when we do a function call, and removed when we return ll d d h t f() {


slide-1
SLIDE 1

Last week

Data can be allocated on the stack

  • r on the heap (aka dynamic memory)
  • r on the heap (aka dynamic memory)
  • Data on the stack is allocated automatically when we do a function

ll d d h t call, and removed when we return

f() { ... int table[len]; .... }

  • Data on the heap must be (de)allocated manually, using malloc

and free

int *table = malloc(len*sizeof(int)); ... free(table);

sws1 1

slide-2
SLIDE 2

Stack vs heap

  • To use data on the heap, we must use pointers!
  • therwise the data is lost and we cannot use it

– otherwise the data is lost and we cannot use it

  • Pointers to data allocated on the heap can be

– on the stack – in the heap itself

You can have pointers from the heap to the stack, but typically you do not need them, or want them!

sws1 2

slide-3
SLIDE 3

Stack Heap

sws1 3

slide-4
SLIDE 4

Memory (security) problems y ( y)

Malicious code, buggy code, and insecure code can access data h th h d t k anywhere on the heap and stack, eg

  • by doing pointer arithmetic
  • by overrunning array bounds

by overrunning array bounds More generally, security problems with memory can be due to 1. running out of memory 2. lack of initialisation of memory 3 bugs in program code 3. bugs in program code esp for heap, as dynamic memory is more complex & error-prone

Hence MISRA-C guidelines for safety-critical software include Hence MISRA-C guidelines for safety-critical software include Rule 20.4 (REQUIRED) Dynamic heap allocation shall not be used

sws1 4

slide-5
SLIDE 5

Running out of stack memory (aka stack overflow) g y ( )

  • Max size of the stack is finite and typically fixed on start-up of a

process process

  • Normally, stack overflow will simply crash a program

– as demo-ed last week

  • Are there sensible alternatives?
  • Are there more dangerous alternatives?

sws1 5

slide-6
SLIDE 6

http://embeddedgurus.com/state-space/2014/02/are-we-shooting-ourselves-in-the-foot-with-stack-overflow/

sws1 6

slide-7
SLIDE 7

sws1 7

slide-8
SLIDE 8

sws1 8

slide-9
SLIDE 9

memory initialisation y

What will this program print? h b char b; printf(”b is %i .\n”, b); // %i to print integer In C memory is not initialised, so b can have any value. Some programming language do provide a default initialisation. Why is that nicer and more secure? programs behave more deterministic; a program with uninitialised

  • programs behave more deterministic; a program with uninitialised

variables can behave differently each time it’s run, which is not nice

  • esp. when debugging
  • for security: by reading uninitialised memory, a program can read

confidential memory contents left there earlier

sws1 9

slide-10
SLIDE 10

calloc

Memory allocated on the heap with malloc is typically not initialised

Many OSs will zero out memory for a new process but recycling of memory

  • Many OSs will zero out memory for a new process, but recycling of memory

within that process means that malloc-ed memory may contain old junk.

  • If OS does not zero out memory for new processes, you can access

fid ti l i f ti l ft i b th b ll i confidential information left in memory by other processes by malloc-ing large chunks of data!

The function calloc will initialise the memory it allocates, to all zeroes

  • downside: this is slower

id Thi i d f i d f idi id i l

  • upside: This is good for security and for avoiding accidential non-

determinism due to missing initialisation in a (buggy) program

  • But, in security-sensitive code, you may still want to zero out

, y , y y confidential information in memory yourself before you free it

sws1 10

slide-11
SLIDE 11

Stack vs heap allocation

Consider

main() {while (true) { f(); } }

What is the difference in behaviour for the two versions of f() below?

()

void f(){ int x[300]; x[0]=0; f (i t i 1 i<300 i++) { [i] [i 1]+i } for (int i=1; i<300; i++) {x[i] = x[i-1]+i;} printf(“result is %i \n”, x[299]); } void f(){ int *x = malloc(300*sizeof(int));

malloc may fail

int *x = malloc(300*sizeof(int)); x[0]=0; for (int i=1; i<300; i++) {x[i] = x[i-1]+i;} printf(“result is %i \n”, x[299]); }

memory leak! the memory of x will remain allocated; so

sws1 11

main will crash when heap memory runs out

slide-12
SLIDE 12

Stack vs heap allocation

void (f){ i t * ll (300* i f(i t)) int *x = malloc(300*sizeof(int)); if (x==NULL) { exit(); } x[0]=0; [ ] ; for (int i=1; i<300; i++) {x[i] = x[i-1]+i;} printf(“result is %i \n”, x[299]); free(x); // to avoid memory leaks } Moral of the story: heap allocation is more work for the programmer

sws1 12

slide-13
SLIDE 13

Heap problems: memory leaks y

Memory leaks occur when you forget to use free correctly. Programs with memory leaks will crash if they run for long enough. You may also notice programs running slower over time if they leak memory. Restarting such a program will help, as it will start with a fresh heap

sws1 13

slide-14
SLIDE 14

More heap problems: dangling pointers g g

Never use memory after it has been de-allocated int *x = malloc (1000); free (x); ( ); ... print(“Let’s use a dangling pointer %s”, x); A pointer to memory that has been de-allocated (freed) is called a dangling pointer When using dangling pointers all bets are off dangling pointer. When using dangling pointers, all bets are off...

sws1 14

slide-15
SLIDE 15

More heap problems: using free incorrectly g y

  • Never free memory that is not dynamically allocated

char *x = ”hello”; char *x = ”hello”; free (x); // error, since ”hello” // is statically allocated

  • Never double free

h * ll (1000) char *x = malloc (1000); free (x); ... free (x); // error

sws1 15

slide-16
SLIDE 16

Memory management trouble: spot the bug y g g

memory leak!

int *x = malloc (1000); int *y = malloc (2000);

memory leak! we cannot access the 2000 bytes that y pointed to and we

y = x;

pointed to, and we cannot free them!

sws1 16

slide-17
SLIDE 17

Aliasing – spot the bug! g g

Aliasing can make some of these bugs hard to spot

int *x = malloc (1000); int *y = malloc (2000); double free! this int *z = x; y = x; int *w = y; memory is already de-allocated in the line above free (w); free (z);

Two pointers are called aliases if they both point to the same address Ali i t th ith th f t th t ll d f h Aliasing, together with the fact that malloc and free can happen in different places of the program, make dynamic memory management extremely tricky!! g y y

sws1 17

slide-18
SLIDE 18

Heap memory management y g

The implementations of malloc and free have to keep track of which t f h till d parts of heap are still unused.

  • Initially, the free memory is one contiguous region.
  • As more blocks are malloc-ed and freed, it becomes messier

free free free free free free used

initially 1 malloc 4 more malloc’s 2 free’s 2 more malloc’s

sws1 18

malloc s malloc s

slide-19
SLIDE 19

Heap memory management y g

The implementations of malloc and free have to keep track of which parts of heap are still unused parts of heap are still unused. How would you do this?

sws1 19

slide-20
SLIDE 20

Example heap management: recording free heap chunks

next end first_free next end NULL end

Inside each free chunk

  • a pointer to the next free chunk

a pointer to the next free chunk

  • a pointer to the end of the current free chunk

Not very efficient: real malloc and free do more admin for efficiency

sws1 20

slide-21
SLIDE 21

Heap memory management y g

One way is to maintain a free list of all the heap chunks that are unused. unused.

  • This info can be recorded on the heap itself, namely in the unused parts of

the heap.

  • You can also maintain meta-information in the used chunks on the heap to

You can also maintain meta information in the used chunks on the heap to help in de-allocation (eg the size of the chunk)

  • NB an attacker can try to corrupt any this data!

Padding malloc-ed data to a round number reduces fragmentation. The programmer can make memory management easier and reduce The programmer can make memory management easier and reduce fragmentation by often allocating chunks of data of the same size.

Malloc-ed data can not be moved or shifted on the heap, because this will break pointers to that data!

sws1 21

slide-22
SLIDE 22

garbage collection g g

In modern programming languages (Java, C#, ...), instead of the h i t f d i th i b programmer having to free dynamic memory, there is a garbage collector which automatically frees memory that is no longer used. Advantage: much less error-prone Disadvantage: performance

  • Garbage collection is an expensive operation (it involves analysis of

the entire heap), so garbage collection brings some overhead.

  • Moreover garbage collection may kick in at unexpected moments
  • Moreover, garbage collection may kick in at unexpected moments,

temporarily resulting in a very bad response time.

Still, there are clever garbage collection schemes suitable for real-time programs.

sws1 22

slide-23
SLIDE 23

Recap: stack vs heap

Stack

  • variables are allocated and de-allocated automatically
  • allocation is much faster than for the heap
  • data on the stack can be used without pointers
  • data needs have to be known at compile time

data needs have to be known at compile time

  • stack space may run out, eg. due to infinite recursions
  • max size of the stack usually fixed by OS when program starts

Heap Heap

  • (de)allocation has to be done manually by the programmer;

this is highly error-prone!

  • allocation of heap memory slower than for stack memory
  • to access data on the heap, you must use pointers;

this is also error-prone! p

  • more flexible, and must to be used when data needs are not known at

compile time

  • heap space may run out too, but can grow during the life time

heap space may run out too, but can grow during the life time

sws1 23

slide-24
SLIDE 24

Lack of memory protection y

Data is typically not initialised when allocated

  • except static global variables

memory allocated by calloc and possibly except static global variables, memory allocated by calloc, and possibly fresh heap memory allocated by malloc the first time it is used

Irrespective of whether we store data on the heap or the stack: Irrespective of whether we store data on the heap or the stack: malicious code , buggy code, and insecure code can access data anywhere on heap or stack, eg

  • by doing pointer arithmetic
  • by overrunning array bounds

Buggy or insecure code acting on malicious input supplied by an attacker can be used for malicious purposes.

Malicious, buggy or insecure code can be in libraries or in, say, a browser plugin.

sws1 24

slide-25
SLIDE 25

Sun tarball problem (1993) ( )

Every tarball produced on Solaris 2.0 contained fragments of the password file / t / d password file /etc/password. How did this happen? How did this happen? – tar looked up user info directly prior to producing tarball:

  • password file was loaded in memory for this
  • this memory was then released

– then tar allocated memory for constructing the tarball ll t d l th j t l d

  • allocated memory was always the memory just released
  • memory not zeroed out on allocation...

Solution: replacing char *buf (char*)malloc(BUFSIZE) by char *buf (char*)calloc(BUFSIZE)

25