sh: Fix TCP payload csum bug in csum_partial_copy_generic().
authorOllie Wild <aaw@rincewind.tv>
Wed, 27 Sep 2006 05:46:24 +0000 (14:46 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 27 Sep 2006 05:46:24 +0000 (14:46 +0900)
There's a bug in the Hitachi SuperH csum_partial_copy_generic()
implementation.  If the supplied length is 1 (and several alignment
conditions are met), the function immediately branches to label 4.
However, the assembly at label 4 expects the length to be stored in
register r2.  Since this has not occurred, subsequent behavior is
undefined.

This can cause bad payload checksums in TCP connections.

I've fixed the problem by initializing register r2 prior to the branch
instruction.

Signed-off-by: Ollie Wild <aaw@rincewind.tv>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/lib/checksum.S

index 7c50dfe68c07707cab8b8e8793a98a423741b68e..cbdd0d40e545f0fa0d5cea817a472f46175f5a47 100644 (file)
@@ -202,8 +202,9 @@ ENTRY(csum_partial_copy_generic)
        cmp/pz  r6              ! Jump if we had at least two bytes.
        bt/s    1f
         clrt
+       add     #2,r6           ! r6 was < 2.   Deal with it.
        bra     4f
-        add    #2,r6           ! r6 was < 2.   Deal with it.
+        mov    r6,r2
 
 3:     ! Handle different src and dest alignments.
        ! This is not common, so simple byte by byte copy will do.