MADV_WIPEONFORK Replaces Inherited Private Memory with Zeroes
A normal fork() gives the child mappings derived from the parent’s address space, with private writable pages commonly handled through copy-on-write. MADV_WIPEONFORK changes that inheritance rule for a selected private anonymous range: the mapping remains present in the child, but its contents are zero-filled there.
The parent keeps its existing bytes. The operation therefore changes child-visible memory at the process-creation boundary rather than erasing the parent’s range.
The mapping survives while its data does not
MADV_WIPEONFORK is passed to madvise() for a page-aligned address range:
void *region = mmap(NULL, len,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
madvise(region, len, MADV_WIPEONFORK);After a successful call, a later fork() produces a child in which the marked range reads as zero-filled memory. This differs from MADV_DONTFORK, which excludes the marked pages from the child’s address space instead of retaining a zeroed mapping.
The distinction matters to code that expects an address range to remain structurally available after fork(). With MADV_WIPEONFORK, pointers into the range still refer to mapped memory in the child, but the prior payload is absent.
The advice is restricted to private anonymous memory
Linux applies MADV_WIPEONFORK only to private anonymous mappings. A range containing file-backed memory, Huge TLB memory, MAP_SHARED memory, or VM_PFNMAP areas is not eligible and can cause madvise() to fail with EINVAL.
That boundary matches the operation’s semantics. The kernel is replacing inherited process-private state, not redefining the contents of a shared object or a file mapping.
The address supplied to madvise() must also satisfy Linux’s page-alignment requirement. The requested size is rounded to page granularity by the interface.
The child inherits the wipe-on-fork attribute
The first fork does not consume the setting. In the child, the affected range remains marked with MADV_WIPEONFORK. If that child later calls fork(), its descendant receives zero-filled memory for the same range as well.
This persistence makes the attribute part of the mapping state across a fork lineage. MADV_KEEPONFORK reverses the setting for a range when ordinary fork inheritance is required again.
An execve() boundary is different: the wipe-on-fork setting is cleared during execve(). That fits the larger address-space replacement performed by execution of a new program image.
Zeroing at fork is narrower than general memory erasure
The flag is suited to process-private material that should exist in the parent but should not be copied into newly forked children. Linux documentation cites data such as PRNG seeds and cryptographic secrets as examples.
Its guarantee is specific to fork inheritance. It is not a general secure-erasure primitive for the parent’s memory, does not retroactively affect children that already exist, and does not apply to arbitrary mapping types.
The useful boundary is precise: MADV_WIPEONFORK preserves the selected private anonymous mapping in each new child while replacing the inherited payload with zeroes. Code that needs the mapping to disappear entirely has a different mechanism in MADV_DONTFORK; code that needs normal inheritance can restore it with MADV_KEEPONFORK.