| From b3f4f51ea68a495f8a5956064c33dce711a2df91 Mon Sep 17 00:00:00 2001 |
| From: Rasmus Villemoes <linux@rasmusvillemoes.dk> |
| Date: Fri, 21 Oct 2022 08:01:53 +0200 |
| Subject: tools/nolibc/string: Fix memcmp() implementation |
| |
| From: Rasmus Villemoes <linux@rasmusvillemoes.dk> |
| |
| commit b3f4f51ea68a495f8a5956064c33dce711a2df91 upstream. |
| |
| The C standard says that memcmp() must treat the buffers as consisting |
| of "unsigned chars". If char happens to be unsigned, the casts are ok, |
| but then obviously the c1 variable can never contain a negative |
| value. And when char is signed, the casts are wrong, and there's still |
| a problem with using an 8-bit quantity to hold the difference, because |
| that can range from -255 to +255. |
| |
| For example, assuming char is signed, comparing two 1-byte buffers, |
| one containing 0x00 and another 0x80, the current implementation would |
| return -128 for both memcmp(a, b, 1) and memcmp(b, a, 1), whereas one |
| of those should of course return something positive. |
| |
| Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> |
| Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") |
| Cc: stable@vger.kernel.org # v5.0+ |
| Signed-off-by: Willy Tarreau <w@1wt.eu> |
| Signed-off-by: Paul E. McKenney <paulmck@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| tools/include/nolibc/nolibc.h | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/tools/include/nolibc/nolibc.h |
| +++ b/tools/include/nolibc/nolibc.h |
| @@ -2318,9 +2318,9 @@ static __attribute__((unused)) |
| int memcmp(const void *s1, const void *s2, size_t n) |
| { |
| size_t ofs = 0; |
| - char c1 = 0; |
| + int c1 = 0; |
| |
| - while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) { |
| + while (ofs < n && !(c1 = ((unsigned char *)s1)[ofs] - ((unsigned char *)s2)[ofs])) { |
| ofs++; |
| } |
| return c1; |