Using the "electric fence" memory allocator, the location of the data
corruption can be narrowed down to the destination address in the memcpy
call in slirp/mbuf.c, function m_cat():
void
m_cat(m, n)
register struct mbuf *m, *n;
{
/*
* If there's no room, realloc
*/
if (M_FREEROOM(m) < n->m_len)
m_inc(m,m->m_size+MINCSIZE);
memcpy(m->m_data+m->m_len, n->m_data, n->m_len); <<<< this memcpy
corrupts the malloc
heap
....
}
The problem is apparently in m_inc(), when an mbuf with an external
data buffer is resized. After resizing the mbuf, the m_data member
still points into the old buffer, before is was reallocated. For some
reason, the code to re-adjust the m_data pointer is present in the M_EXT
case in m_inc(), but is commented out. (With a bit of luck, realloc
might be able to adjust the size of the memory block in place; but
slirp shouldn't rely on this)
Fix: Adjust mbuf->m_data after a realloc of the external data buffer