I'm thinking about re-implementing the malloc(3)
function (as well as free(3)
, realloc(3)
and calloc(3)
) using mmap(2)
and munmap(2)
syscalls (as sbrk(2)
is now deprecated on some operating systems).
My strategy to allocate memory blocks on the page returned by mmap(2)
would be to store metadata right before the block of data. Thus the metadata could consist of 3 attributes:
is_free
: achar
(1 byte) to tell if the block is considered free or not;size
: ansize_t
(4 bytes) with the size of the block in term of bytes;next
: a pointer (1 byte) to the next block's metadata (or to the next page first block if there's no more space after the block).
But as I can't use malloc to allocate a struct for them, I would simply consider putting 6 bytes of metadata in front of the block each time I create one:
+---------+---------+--------+------------------+---------+---------+--------+---------+---
| is_free | size | next | Block1 | is_free | size | next | Block2 | ...
+---------+---------+--------+------------------+---------+---------+--------+---------+---
| 1 byte | 4 bytes | 1 byte | n bytes | 1 byte | 4 bytes | 1 byte | m bytes | ...
+---------+---------+--------+------------------+---------+---------+--------+---------+---
How can I be sure the user/process using my malloc won't be able to read/write the metadata of the blocks with such architecture?
Eg: With the previous schema, I return the Block1's first byte to the user/process. If he/it does *(Block1 + n) = Some1ByteData
he/it can alter the metadata of the next block which will cause issues with my program if I try to allocate a new block later on.
On the mmap(2)
man page I read that I could give protection flags for the pages, but if I use them, then the user/process using my malloc won't be able to use the block I give. How is it achieve in the real malloc?
PS: For the moment I don't consider thread-safe implementation nor looking for top-tier performances. I just want something strong and functional.