A double free breaks invariants for the memory allocator. For example, the freed memory may have been handed out to someone else and if you free it again, it will be marked as unused even though that code relies on their stuff being available. One very classic way of exploiting a double-free is a sequence like this happens:
1. Some code allocates memory.
2. The code frees the memory, but keeps a stale reference to it around. It is marked as unused by the allocator.
3. Some other code allocates memory. Maybe it's reading the password file off of disk. The allocator has some unused memory lying around so it hands it out–but it turns out that this is actually just a reuse of the buffer from earlier. It is now marked as "in use" again by the allocator.
4. The code from earlier has a bug and frees the allocation again. This means that the allocation is now marked as "unused".
5. Another allocation request hands out this memory again. Maybe it's a buffer for user input? Well, it's been scribbled all over with other data now.
6. Someone asks to authenticate and the password checking code gets called. It has the password right here to check against…oh, wait, that memory got freed out from under it and overwritten with some attacker-controlled content!
1. Some code allocates memory.
2. The code frees the memory, but keeps a stale reference to it around. It is marked as unused by the allocator.
3. Some other code allocates memory. Maybe it's reading the password file off of disk. The allocator has some unused memory lying around so it hands it out–but it turns out that this is actually just a reuse of the buffer from earlier. It is now marked as "in use" again by the allocator.
4. The code from earlier has a bug and frees the allocation again. This means that the allocation is now marked as "unused".
5. Another allocation request hands out this memory again. Maybe it's a buffer for user input? Well, it's been scribbled all over with other data now.
6. Someone asks to authenticate and the password checking code gets called. It has the password right here to check against…oh, wait, that memory got freed out from under it and overwritten with some attacker-controlled content!