DF-2570 / fix.diff
diff --git a/sys/netgraph/ng_device.c b/sys/netgraph/ng_device.c index 0000000..1111111 100644 --- a/sys/netgraph/ng_device.c +++ b/sys/netgraph/ng_device.c @@ -360,22 +360,21 @@ return(-1); } - buffer = kmalloc(sizeof(char)*m->m_len, M_DEVBUF, M_NOWAIT | M_ZERO); - if(buffer == NULL) { - kprintf("%s(): ERROR: buffer malloc failed\n", __func__); - return(-1); - } - - buffer = mtod(m, char *); - + /* + * DF-2570 defense-in-depth fix: operate on the mbuf's data pointer + * directly. The previous code kmalloc()'d a buffer from M_DEVBUF, + * immediately leaked that pointer by reassigning it to mtod(m), + * and then kfree()'d the mbuf's m_data through the WRONG zone + * (M_DEVBUF), corrupting the mbuf slab and producing a + * double-freeable mbuf when the mbuf was later freed through its + * own zone. The intermediate buffer served no purpose. + */ if( (connection->loc+m->m_len) < NGD_QUEUE_SIZE) { - memcpy(connection->readq+connection->loc, buffer, m->m_len); + memcpy(connection->readq+connection->loc, mtod(m, char *), m->m_len); connection->loc += m->m_len; } else kprintf("%s(): queue full, first read out a bit\n", __func__); - kfree(buffer, M_DEVBUF); - return(0); } |