[glibc/azanella/ubsan-undef] string: Fix UB on index_first/index_last
Adhemerval Zanella
azanella@sourceware.org
Wed May 7 14:15:37 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=a67a8eda72ad95b265db9ea1d3b914c9a1d9a5c9
commit a67a8eda72ad95b265db9ea1d3b914c9a1d9a5c9
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Tue Apr 22 14:34:27 2025 -0300
string: Fix UB on index_first/index_last
Building with ubsan the test-strcnmp triggers:
UBSAN: Undefined behaviour in ../sysdeps/generic/string-fzi.h:39:12 passing zero to __builtin_ctz()
Use stdbit.h functions instead of ctl/clz.
Diff:
---
sysdeps/generic/string-fzi.h | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
diff --git a/sysdeps/generic/string-fzi.h b/sysdeps/generic/string-fzi.h
index 3c1028d1ec..f90f662ac2 100644
--- a/sysdeps/generic/string-fzi.h
+++ b/sysdeps/generic/string-fzi.h
@@ -19,28 +19,11 @@
#ifndef _STRING_FZI_H
#define _STRING_FZI_H 1
+#include <stdbit.h>
#include <limits.h>
#include <endian.h>
#include <string-fza.h>
-static __always_inline int
-clz (find_t c)
-{
- if (sizeof (find_t) == sizeof (unsigned long))
- return __builtin_clzl (c);
- else
- return __builtin_clzll (c);
-}
-
-static __always_inline int
-ctz (find_t c)
-{
- if (sizeof (find_t) == sizeof (unsigned long))
- return __builtin_ctzl (c);
- else
- return __builtin_ctzll (c);
-}
-
/* A subroutine for the index_zero functions. Given a test word C, return
the (memory order) index of the first byte (in memory order) that is
non-zero. */
@@ -49,9 +32,9 @@ index_first (find_t c)
{
int r;
if (__BYTE_ORDER == __LITTLE_ENDIAN)
- r = ctz (c);
+ r = stdc_trailing_zeros (c);
else
- r = clz (c);
+ r = stdc_leading_zeros (c);
return r / CHAR_BIT;
}
@@ -62,9 +45,9 @@ index_last (find_t c)
{
int r;
if (__BYTE_ORDER == __LITTLE_ENDIAN)
- r = clz (c);
+ r = stdc_leading_zeros (c);
else
- r = ctz (c);
+ r = stdc_trailing_zeros (c);
return sizeof (find_t) - 1 - (r / CHAR_BIT);
}
More information about the Glibc-cvs
mailing list