Commit 4e0262af authored by Martin Michlmayr's avatar Martin Michlmayr

Fix wrong checksum for split TCP packets on 64-bit MIPS

svn path=/dists/etch/linux-2.6/; revision=8505
parent 384b168b
......@@ -22,6 +22,9 @@ linux-2.6 (2.6.18.dfsg.1-13) UNRELEASED; urgency=low
* Backport support for i965 to agp too. (closes: #406111)
* Compile fix for UML CONFIG_MODE_TT=y. (closes: #412957)
[ Martin Michlmayr ]
* Fix wrong checksum for split TCP packets on 64-bit MIPS
-- maximilian attems <maks@debian.org> Tue, 24 Apr 2007 20:13:49 +0200
linux-2.6 (2.6.18.dfsg.1-12etch1) stable-security; urgency=high
......
Author: Dave Johnson <djohnson+linux-mips@sw.starentnetworks.com> Wed Apr 18 10:39:41 2007 -0400
Comitter: Ralf Baechle <ralf@linux-mips.org> Wed Apr 18 17:13:29 2007 +0100
Commit: d3b6f8214113e8bad8a0ce3ab1d37b6be1e5a22e
Gitweb: http://www.linux-mips.org/g/linux/d3b6f821
Branch: linux-2.6.18-stable
I've traced down an off-by-one TCP checksum calculation error under
the following conditions:
1) The TCP code needs to split a full-sized packet due to a reduced
MSS (typically due to the addition of TCP options mid-stream like
SACK).
_AND_
2) The checksum of the 2nd fragment is larger than the checksum of the
original packet. After subtraction this results in a checksum for
the 1st fragment with bits 16..31 set to 1. (this is ok)
_AND_
3) The checksum of the 1st fragment's TCP header plus the previously
32bit checksum of the 1st fragment DOES NOT cause a 32bit overflow
when added together. This results in a checksum of the TCP header
plus TCP data that still has the upper 16 bits as 1's.
_THEN_
4) The TCP+data checksum is added to the checksum of the pseudo IP
header with csum_tcpudp_nofold() incorrectly (the bug).
The problem is the checksum of the TCP+data is passed to
csum_tcpudp_nofold() as an 32bit unsigned value, however the assembly
code acts on it as if it is a 64bit unsigned value.
This causes an incorrect 32->64bit extension if the sum has bit 31
set. The resulting checksum is off by one.
This problems is data and TCP header dependent due to #2 and #3
above so it doesn't occur on every TCP packet split.
Signed-off-by: Dave Johnson <djohnson+linux-mips@sw.starentnetworks.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
(cherry picked from commit 3be5b819ac5c9395b60556ae3434ff62d7ded2e7)
---
include/asm-mips/checksum.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
index a5e6050..5f71650 100644
--- a/include/asm-mips/checksum.h
+++ b/include/asm-mips/checksum.h
@@ -159,7 +159,7 @@ static inline unsigned int csum_tcpudp_nofold(unsigned long saddr,
#else
"r" (((unsigned long)(proto)<<16) + len),
#endif
- "r" (sum));
+ "r" ((__force unsigned long)sum));
return sum;
}
+ bugfix/listxattr-mem-corruption.patch
+ features/agp-i965.patch
+ bugfix/fix-syscallX-uml.patch
+ bugfix/mips/tcp-checksum.patch
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment