Messages in this thread | | | Date | Mon, 02 Jun 1997 12:13:09 -0400 | From | Bill Hawes <> | Subject | Bug in IP accounting explained |
| |
Jos Vos wrote:
> B.t.w., the corrupted data problem is there since long, probably forever.
I've figured out the IP accounting bug, and you're right, it's probably been there forever. Here's what's happening:
To get IP accounting, the ip_chain_procinfo routine has to walk a linked list using sprintf() to copy data elements into a buffer. On some systems the linked list may be long, so the converted data won't fit in the buffer. So ip_chain_procinfo returns as many entries will fit, and the file offset is updated to reflect that many.
When the next call to ip_chain_procinfo comes in, the only state that's passed is in the file offset. Hence it has to rewalk the list, converting all the entries again to get up to the point where it left off last time. The problem is that the linked list elements copied out the first time may have changed, and the new conversion by sprintf() may not be the same length as before. But ip_chain_procinfo returns the starting buffer position corresponding to the file offset, and so may chop off part of the new data being returned.
There's an easy cheesy fix, which is just to make all of the sprintf() format conversions have a fixed width, so that the converted length can't change between calls. The right way to fix it would be to make all the returned lines the same length, then divide the offset by the length to calculate how many list nodes to skip over before starting the new conversion.
This same problem could apply to any /proc entry that has to walk a linked list where the length of the data converted may change between calls. If an entry required many calls to complete, it would result in something on the order of N**2 sprintf conversions being done (and with interrupts turned off in each call.)
I'd be glad to make the fix to ip_fw.c, unless someone else wants to (who's the maintainer now? Alan?)
-Bill
| |