lib/checksum.c: use 32-bit arithmetic consistently
authorArnd Bergmann <arnd@arndb.de>
Tue, 23 Jun 2009 19:22:58 +0000 (21:22 +0200)
committerArnd Bergmann <arnd@arndb.de>
Tue, 3 Nov 2009 15:06:52 +0000 (16:06 +0100)
The use of 'unsigned long' variables in the 32-bit part of do_csum()
is confusing at best, and potentially broken for long input on 64-bit
machines.

This changes the code to use 'unsigned int' instead, which makes
the code behave in the same (correct) way on both 32 and 64 bit
machines.

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
lib/checksum.c

index b2e2fd4..886b48d 100644 (file)
@@ -37,7 +37,7 @@
 
 #include <asm/byteorder.h>
 
-static inline unsigned short from32to16(unsigned long x)
+static inline unsigned short from32to16(unsigned int x)
 {
        /* add up 16-bit and 16-bit for 16+c bit */
        x = (x & 0xffff) + (x >> 16);
@@ -49,7 +49,7 @@ static inline unsigned short from32to16(unsigned long x)
 static unsigned int do_csum(const unsigned char *buff, int len)
 {
        int odd, count;
-       unsigned long result = 0;
+       unsigned int result = 0;
 
        if (len <= 0)
                goto out;
@@ -73,9 +73,9 @@ static unsigned int do_csum(const unsigned char *buff, int len)
                }
                count >>= 1;            /* nr of 32-bit words.. */
                if (count) {
-                       unsigned long carry = 0;
+                       unsigned int carry = 0;
                        do {
-                               unsigned long w = *(unsigned int *) buff;
+                               unsigned int w = *(unsigned int *) buff;
                                count--;
                                buff += 4;
                                result += carry;