Is malloc deterministic? Is malloc deterministic? linux linux

Is malloc deterministic?


There is no reason at all for it to be deterministic, in fact there can be some benefit to it not being deterministic, for example increasing the complexity of exploiting bugs (see also this paper).

This randomness can be helpful at making exploits harder to write. To successfully exploit a buffer overflow you typically need to do two things:

  1. Deliver a payload into a predictable/known memory location
  2. Cause execution to jump to that location

If the memory location is unpredictable making that jump can become quite a lot harder.

The relevant quote from the standard ยง7.20.3.3/2:

The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate

If it were the intention to make it deterministic then that would be clearly stated as such.

Even if it looks deterministic today I wouldn't bet on it remaining so with a newer kernel or a newer libc/GCC version.


The C99 spec (at least, in its final public draft) states in 'J.1 Unspecified behavior':

The following are unspecified: ... The order and contiguity of storage allocated by successive calls to the calloc, malloc, and realloc functions (7.20.3).

So it would seem that malloc doesn't have to be deterministic. It therefore isn't safe to assume that it is.


That depends entirely on the malloc implementation. There's no inherent reason why a particular malloc implementation would introduce non-determinism (except possibly as an application fuzzing test, but even then it ought to be disabled by default). For example, Doug Lea's malloc does not use rand(3) or any similar methods in it.

But, since malloc makes calls to the kernel such as sbrk(2) or mmap(2) on Linux or VirtualAlloc on Windows, those system calls may not always be deterministic, even in otherwise identical processes. The kernel may decide to intentionally provide different mmap'ed addresses in different processes for whatever reason.

So for small allocations, which are usually serviced in user space without a system call, it will quite likely be the case that the resulting pointers will be the same after a fork(); large allocations that are serviced by a system a call can be the same.

In general, though, do not depend on it. If you really need identical pointers in separate processes, either create them before forking, or use shared memory and share them appropriately.