[lkml]   [2002]   [Feb]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
SubjectRe: memory corruption in tcp bind hash buckets on SMP?

There is a scenario that leaves a tw in bind hash list even after it gets
deallocated: (seems like easy to fix):

There is a fix that went into between 2.4.16 & 17 (this fix made into into
both RH 2.4.9-etc.. _and_ 2.4.7-10). Fix is to do atomic_set(tw->refcnt, 1)
instead of 0 and do tcp_tw_put(tw) after tcp_tw_schedule() in
tcp_time_wait(). It looks like this may not be complete fix for tw's
refcnting issues.

Here is how it happens: reference code 2.4.9-21 (applies to 2.4.17 as well):

Proc 0 Proc 1
-------------------------- | ------------------------

gets ACK for an sk and sk | The remote side sent RST immediately
goes into FIN_WAIT2 state. | after ACK for our FIN (abortive
So we are in __tcp_hashdance(). | close). RST was processed on proc 1.
We just did | since this is an RST, we go to
write_unlock(ehead->lock); | tcp_timewait_state_process()
| and kill: label in there
| which
| calls tcp_timewait_kill().
| Here, we delete tw from ehash list.
| but "if ((tb = tw->tb) != NULL)" fails
| 'cause this has not been inserted
| on proc 0 yet.
| Now we go ahead and do tcp_tw_put().

So now we schedule_tw() on proc 0 and when the timeout fires, we call
tcp_timewait_kill() again. But now tw->pprev is NULL (because it was deleted
from established hash above by proc 1). So we just return with out deleting
it from the bind hash list!!. A simple fix is to increment refcnt once for
each list addition and decrement it once for each list deletion or decremnt
only only when it is delete from bind hash. of course 'return if tw->pprev ==
NULL' should also be removed.

we have seen this happening (eg, tw->tb is non null just before kfree(tw)).


--- "David S. Miller" <> wrote:
> From: Raghu Angadi <>
> Date: Wed, 13 Feb 2002 16:51:52 -0800 (PST)
> --- "David S. Miller" <> wrote:
> >
> > This bug is fixed in the 2.4.9 Red Hat 7.2 errata kernels.
> Thanks, Is the following diff the only culprit/fix?
> There are others, seatch for more instances of tcp_tw_get()
> and tcp_tw_put() and things like atomic_set(tw->count, 1);

Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

 \ /
  Last update: 2005-03-22 13:24    [W:0.093 / U:9.400 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site