Skip to content

Commit

Permalink
strcmp: fix overflow and possibly signedness error
Browse files Browse the repository at this point in the history
Doing the strcmp return value as

	signed char __res = *cs - *ct;

is wrong for two reasons.  The subtraction can overflow because __res
doesn't use a type big enough.  Moreover the compared bytes should be
interpreted as unsigned char as specified by POSIX.

The same problem is fixed in strncmp.

Signed-off-by: Uwe Kleine-König <[email protected]>
Cc: Michael Buesch <[email protected]>
Cc: Andreas Schwab <[email protected]>
Cc: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
torvalds committed Nov 19, 2009
1 parent 6602b35 commit a414f01
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions lib/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,17 @@ EXPORT_SYMBOL(strlcat);
#undef strcmp
int strcmp(const char *cs, const char *ct)
{
signed char __res;
unsigned char c1, c2;

while (1) {
if ((__res = *cs - *ct++) != 0 || !*cs++)
c1 = *cs++;
c2 = *ct++;
if (c1 != c2)
return c1 < c2 ? -1 : 1;
if (!c1)
break;
}
return __res;
return 0;
}
EXPORT_SYMBOL(strcmp);
#endif
Expand All @@ -266,14 +270,18 @@ EXPORT_SYMBOL(strcmp);
*/
int strncmp(const char *cs, const char *ct, size_t count)
{
signed char __res = 0;
unsigned char c1, c2;

while (count) {
if ((__res = *cs - *ct++) != 0 || !*cs++)
c1 = *cs++;
c2 = *ct++;
if (c1 != c2)
return c1 < c2 ? -1 : 1;
if (!c1)
break;
count--;
}
return __res;
return 0;
}
EXPORT_SYMBOL(strncmp);
#endif
Expand Down

0 comments on commit a414f01

Please sign in to comment.