lib/checksum.c: use 32-bit arithmetic consistently
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>
This commit is contained in:
parent
b6727b12dd
commit
c44ba9f668
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#include <asm/byteorder.h>
|
#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 */
|
/* add up 16-bit and 16-bit for 16+c bit */
|
||||||
x = (x & 0xffff) + (x >> 16);
|
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)
|
static unsigned int do_csum(const unsigned char *buff, int len)
|
||||||
{
|
{
|
||||||
int odd, count;
|
int odd, count;
|
||||||
unsigned long result = 0;
|
unsigned int result = 0;
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
@ -73,9 +73,9 @@ static unsigned int do_csum(const unsigned char *buff, int len)
|
|||||||
}
|
}
|
||||||
count >>= 1; /* nr of 32-bit words.. */
|
count >>= 1; /* nr of 32-bit words.. */
|
||||||
if (count) {
|
if (count) {
|
||||||
unsigned long carry = 0;
|
unsigned int carry = 0;
|
||||||
do {
|
do {
|
||||||
unsigned long w = *(unsigned int *) buff;
|
unsigned int w = *(unsigned int *) buff;
|
||||||
count--;
|
count--;
|
||||||
buff += 4;
|
buff += 4;
|
||||||
result += carry;
|
result += carry;
|
||||||
|
Loading…
Reference in New Issue
Block a user