Subject: Re: 32/64 sign-extension bug in TCP
To: Ignatios Souvatzis <is@netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: tech-net
Date: 05/03/2004 09:44:00
--zYM0uCDKw75PZbzx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

ok, since my original proposed patch generated more controversy than
I'm comfortable with so close to the 2.0 release, I'll propose
a simpler patch that addresses only the problem at hand, by casting
the uint32_t value to int32_t before casting to long.  this will
cause the value to be sign-extended on LP64 platforms and the code
will do what was intended.  does anyone see any problem with this
simpler change?

the larger LP64 issues in the TCP code can wait until after 2.0
(unless someone else wants to work on them in the very near future).

-Chuck

--zYM0uCDKw75PZbzx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.tcp.simpler"

Index: netinet/tcp_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_output.c,v
retrieving revision 1.111
diff -u -p -r1.111 tcp_output.c
--- netinet/tcp_output.c	26 Apr 2004 03:54:29 -0000	1.111
+++ netinet/tcp_output.c	3 May 2004 15:32:08 -0000
@@ -1043,8 +1043,8 @@ send:
 		win = 0;
 	if (win > (long)TCP_MAXWIN << tp->rcv_scale)
 		win = (long)TCP_MAXWIN << tp->rcv_scale;
-	if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
-		win = (long)(tp->rcv_adv - tp->rcv_nxt);
+	if (win < (long)(int32_t)(tp->rcv_adv - tp->rcv_nxt))
+		win = (long)(int32_t)(tp->rcv_adv - tp->rcv_nxt);
 	th->th_win = htons((u_int16_t) (win>>tp->rcv_scale));
 	if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
 		u_int32_t urp = tp->snd_up - tp->snd_nxt;

--zYM0uCDKw75PZbzx--