Explorar el Código

fix possible overflow in pointer arithmetics strnlen()

It is undefined behavior to compare two pointers belonging to different
objects. This includes the case where the addition overflows. Clang-20
seems to follow this rule more eagerly and optimizes away the old test.

Fix the test by performing the addition on uintptr_t values rather than
on on char pointers.

See also https://github.com/llvm/llvm-project/issues/121909.

Signed-off-by: Marcus Haehnel <marcus.haehnel@kernkonzept.com>
Frank Mehnert hace 9 meses
padre
commit
b92057584f
Se han modificado 1 ficheros con 4 adiciones y 2 borrados
  1. 4 2
      libc/string/generic/strnlen.c

+ 4 - 2
libc/string/generic/strnlen.c

@@ -29,15 +29,17 @@
    '\0' terminator is found in that many characters, return MAXLEN.  */
 size_t strnlen (const char *str, size_t maxlen)
 {
-  const char *char_ptr, *end_ptr = str + maxlen;
+  const char *char_ptr, *end_ptr;
   const unsigned long int *longword_ptr;
   unsigned long int longword, himagic, lomagic;
 
   if (maxlen == 0)
     return 0;
 
-  if (__builtin_expect (end_ptr < str, 0))
+  if (__builtin_expect ((uintptr_t)str + maxlen < (uintptr_t)str, 0))
     end_ptr = (const char *) ~0UL;
+  else
+    end_ptr = str + maxlen;
 
   /* Handle the first few characters by reading one character at a time.
      Do this until CHAR_PTR is aligned on a longword boundary.  */