Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lock the memory to physical RAM in C for the dynamically allocate pointer

Tags:

I want to lock the memory to physical RAM in C with mlock and munlock, but I'm unsure about the correct usage.

Allow me to explain in a step by step scenario:

Let's assume that I dynamically allocate a pointer using calloc:

char * data = (char *)calloc(12, sizeof(char*));

Should I do mlock right after that?

Let's also assume that I later attempt to resize the memory block with realloc:

(char *)realloc(data, 100 * sizeof(char*));

Note the above increase amount ( 100 ) is random and sometimes i will decrease the memory block.

Should I first do munlock and then mlock again to address the changes made?

Also when I want to free the pointer data later, should I munlock first?

I hope someone can please explain the correct steps to me so I can understand better.

like image 857
Jorhn Madsen Avatar asked Mar 13 '20 19:03

Jorhn Madsen


2 Answers

From the POSIX specification of mlock() and munlock():

The mlock() function shall cause those whole pages containing any part of the address space of the process starting at address addr and continuing for len bytes to be memory-resident until unlocked or until the process exits or execs another process image. The implementation may require that addr be a multiple of {PAGESIZE}.

The munlock() function shall unlock those whole pages containing any part of the address space of the process starting at address addr and continuing for len bytes, regardless of how many times mlock() has been called by the process for any of the pages in the specified range. The implementation may require that addr be a multiple of {PAGESIZE}.

Note that:

  • Both functions work on whole pages
  • Both functions might require addr to be a multiple of page size
  • munlock doesn't use any reference counting to track lock lifetime

This make it almost impossible to use them with pointers returned by malloc/calloc/realloc as they can:

  • Accidently lock/unlock nearby pages (you might unlock pages that must be memory-resident by accident)
  • Might return pointers that are not suitable for those functions

You should use mmap instead or any other OS-specific mechanism. For example Linux has mremap which allows you to "reallocate" memory. Whatever you use, make sure mlock behavior is well-defined for it. From Linux man pages:

If the memory segment specified by old_address and old_size is locked (using mlock(2) or similar), then this lock is maintained when the segment is resized and/or relocated. As a consequence, the amount of memory locked by the process may change.


Note Nate Eldredge's comment below:

Another problem with using realloc with locked memory is that the data will be copied to the new location before you have a chance to find out where it is and lock it. If your purpose in using mlock is to ensure that sensitive data never gets written out to swap, this creates a window of time where that might happen.

like image 51
StaceyGirl Avatar answered Oct 02 '22 15:10

StaceyGirl


TL;DR

  1. Memory locking doesn't mix with general-purpose memory allocation using the C language runtime.

  2. Memory locking does mix with page-oriented virtual memory mapping OS-level APIs.

  3. The above hold unless special circumstances arise (that's my way out of this :)

like image 40
Kuba hasn't forgotten Monica Avatar answered Oct 02 '22 15:10

Kuba hasn't forgotten Monica