Skip to contentSkip to conversation

memcmp() doesn't

PATCH New Georg Nikodym 1 participant 2 messages Feb 13, 2002 – Feb 14, 2002

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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

#1 lore raw

PATCH 1/1 memcmp() kernel janitor (was: memcmp() doesn't)

Quoted 2 lines · Georg Nikodym

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:

lib/string.c +1 -1
@@ -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)