memcmp() doesn't
Subsystems (2)
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
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 )