Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jun 2005 17:38:04 +0900 (JST)
From:      Noritoshi Demizu <demizu@dd.iij4u.or.jp>
To:        Dikshie <dikshie@ppk.itb.ac.id>
Cc:        freebsd-current@freebsd.org, Kris Kennaway <kris@obsecurity.org>
Subject:   Another panic in tcp_sack_option() (Re: ***SPAM Level 2*** Re: doadump () at pcpu.h:165)
Message-ID:  <20050615.173804.85686621.Noritoshi@Demizu.ORG>
In-Reply-To: <20050615051807.GA5076@ppk.itb.ac.id>
References:  <20050614063148.GA22683@ppk.itb.ac.id> <20050614182127.GA22085@xor.obsecurity.org> <20050615051807.GA5076@ppk.itb.ac.id>

next in thread | previous in thread | raw e-mail | index | archive | help
> > >     optlen=0) at /usr/src/sys/netinet/tcp_sack.c:478
> > Here is the real panic, not the frame #0 as in your subject.
> > I've seen this panic also and have reported it to ps and mohan.
> thanks ! I've been disable sack via sysctl it seems solve the problem.

I am sorry for the inconvenience you experienced.
The patch below is another work around of this problem.
I'm working on the real fix.  Wait for days, please.

<<< details start >>>
tcp_sack_option() assumes that, when SACK holes exist,
(TAILQ_FIRST(&tp->snd_holes)->start == tp->snd_una) is always true.
(i.e., the start of the first SACK hole is equal to SND.UNA)
If this holds true, since all SACK blocks in sack_blocks[] satisfy
sblkp->start > tp->snd_una, sack_blocks[] must be consumed earlier
than SACK holes in the while-loop.

I think the fail of the KASSERT() indicates that the formula above
does not hold in some situation.  The only case I can come up with
for now is the follwoing.
  1. A segment comes.
  2. tcp_sack_option() is called without any problem.
  3. tcp_del_sackholes() is called and TAILQ_FIRST(&tp->snd_holes)->start
     is advanced by the ack number on the segment.
  3. The segment is dropped because it fails the PAWS test or some
     other check in tcp_input().
  4. Next segment comes.
  5. tcp_sack_option() is called.  Since TAILQ_FIRST(&tp->snd_holes)->start
     is higher than tp->snd_una, the KASSERT() in the while-loop fails.

I'm working to move the calls of tcp_sack_option() and tcp_del_sackholes()
from the current places to a place after the PAWS test and other checks.
It works on my machine.  But I need more tests and reviews.  So, please
wait for days.
<<< details end >>>

Thanks.

Regards,
Noritoshi Demizu


Index: tcp_sack.c
===================================================================
RCS file: /home/cvsup/FreeBSD/ncvs/src/sys/netinet/tcp_sack.c,v
retrieving revision 1.24
diff -u -r1.24 tcp_sack.c
--- tcp_sack.c	9 Jun 2005 17:55:29 -0000	1.24
+++ tcp_sack.c	15 Jun 2005 08:08:17 -0000
@@ -474,8 +474,7 @@
 	 * Since the incoming sack blocks are sorted, we can process them
 	 * making one sweep of the scoreboard.
 	 */
-	while (sblkp - sack_blocks >= 0) {
-		KASSERT(cur != NULL, ("cur != NULL"));
+	while (sblkp - sack_blocks >= 0 && cur != NULL) {
 		if (SEQ_GEQ(sblkp->start, cur->end)) {
 			/*
 			 * SACKs data beyond the current hole.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050615.173804.85686621.Noritoshi>