2002-02-13 03:52:10

by Georg Nikodym

[permalink] [raw]
Subject: memcmp() doesn't

User's of X86 won't care but the generic memcmp() routine in
lib/string.c is incorrect...

The code reads:

/**
* memcmp - Compare two areas of memory
* @cs: One area of memory
* @ct: Another area of memory
* @count: The size of the area.
*/
int memcmp(const void * cs,const void * ct,size_t count)
{
const unsigned char *su1, *su2;
signed char res = 0;

for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
if ((res = *su1 - *su2) != 0)
break;
return res;
}

Trouble is that the variable res is not big enough to hold all possible
results of a subtraction of two unsigned char quantities.

Changing res to int fixes things (and in the case of ARM, makes the
function smaller).

I can supply patches in BK or regular form but I suspect it'd be easier
for somebody "in the club" to simply make this change themselves.

-g


2002-02-14 14:40:02

by Georg Nikodym

[permalink] [raw]
Subject: [PATCH] memcmp() kernel janitor (was: memcmp() doesn't)

On Tue, 2002-02-12 at 22:51, Georg Nikodym wrote:

> I can supply patches in BK or regular form but I suspect it'd be easier
> for somebody "in the club" to simply make this change themselves.

At the prompting of Ingo Oeser, here's a patch. A BK patch has already
been sent to Linus.

CSET comment:

Fix generic memcmp() to correctly sign the return value.

Non x86 architectures using memcmp() in situations where the sign
of the return value matters would get the wrong answer (in
signed 8-bit arithmetic, 0 - 221 = 35, rather than the -221
that many might assume/expect).

Patch:

--- a/lib/string.c Thu Feb 14 09:33:48 2002
+++ b/lib/string.c Thu Feb 14 09:33:48 2002
@@ -452,7 +452,7 @@
int memcmp(const void * cs,const void * ct,size_t count)
{
const unsigned char *su1, *su2;
- signed char res = 0;
+ int res = 0;

for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
if ((res = *su1 - *su2) != 0)