Qi Zhang
Qi Zhang

Reputation: 721

How to prevent a malicious function from accessing the heap memory that it is not expected to access?

For a given process, the heap space is shared among all the functions, which can result in some security concerns. In the following code, for example, the function main() is expecting the function foo() to only access the 1024 bytes allocated to p. But the function foo(), if it is malicious, can access the memory out of that range.

One of the approaches to prevent this from happening is to restrict foo() to only access the 1024 bytes allocated to p. Is it necessary to do this? If yes, how can we implement this capability, or is there any other approach to achieve this goal?

void foo(char *p){
     printf("value of (p + 2048) is %x\n", *(p + 2048));
}

void main(void){
     size_t size = 1024;
     char *p = malloc(size);

     foo(p);
}

Upvotes: 2

Views: 170

Answers (1)

Susam Pal
Susam Pal

Reputation: 34284

No, there is no way to restrict foo() to accessing only the 1024 bytes allocated for it. A malicious function can always attempt to access past the buffer allocated for it. Some damage it may cause (such as denial-of-service attack by crashing the main service) can be limited by ensuring that foo() is called in a separate process as a user with limited privilege (see POLA).

However, the restriction to access only a limited amount of buffer is usually implemented with the following measures where we assume that foo() is ready to cooperate with its caller. These measures are pointless if foo() is intentionally trying to do harm.

  1. Pass the size around: Pass the size of the allocated buffer to the function foo().
  2. Code carefully: Write the function foo() carefully such that it respects the size of the allocated buffer passed to it and never accesses memory beyond this allocated buffer.
  3. Link to trusted code only: If foo() belongs to a third-party code, ensure that the third-party code can be trusted.

For example,

void foo(char *p, size_t size){
    /* printf("value of (p + 2048) is %x\n", *(p + 2048)); */
    /* Ensure that this function does not access memory only between
       p[0] and p[size - 1], inclusive. */ 
}

void main(void){
     size_t size = 1024;
     char *p = malloc(size);

     foo(p, size);
}

There are only two situations when the function foo() may act maliciously.

  1. Function foo() relies on external input to decide the memory location to be accessed and that external input can somehow cause foo() to access memory beyond p[size - 1]. This is buffer overflow and needs to be avoided by input validation (code carefully; see point 2 above).
  2. The function foo() comes from another library that you do not trust. Using a library that you do not trust is a bad idea anyway. That library could do things far more worse than buffer overflow. So one has to ensure that the library is good and behaves well before using it. One must never link to an untrusted library (link to trusted code only; see point 3 above).

Upvotes: 2

Related Questions