Message ID | AM5PR0801MB166806B712493069237DB5D383A49@AM5PR0801MB1668.eurprd08.prod.outlook.com |
---|---|
State | New |
Headers | show |
Series | Add bounds check to __libc_ifunc_impl_list | expand |
On 08/06/2022 13:28, Wilco Dijkstra via Libc-alpha wrote: > Add a proper bounds check to __libc_ifunc_impl_list. This makes MAX_IFUNC > redundant and fixes several targets that will write outside the array. > To avoid unnecessary large diffs, pass the maximum in the argument 'i' to > IFUNC_IMPL_ADD - 'max' can be used in new ifunc definitions and existing > ones can be updated if desired. > > OK for commit? LGTM, thanks. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > > --- > > diff --git a/include/ifunc-impl-list.h b/include/ifunc-impl-list.h > index 78087f015ccce4172de3c537b9197cd3d6e199fd..00bf48f3f1e182dcd0862a40ac901ee954019d17 100644 > --- a/include/ifunc-impl-list.h > +++ b/include/ifunc-impl-list.h > @@ -34,15 +34,15 @@ struct libc_ifunc_impl > > /* Add an IFUNC implementation, IMPL, for function FUNC, to ARRAY with > USABLE at index I and advance I by one. */ > -#define IFUNC_IMPL_ADD(array, i, func, usable, impl) \ > +#define IFUNC_IMPL_ADD(array, max, func, usable, impl) \ > extern __typeof (func) impl attribute_hidden; \ > - (array)[i++] = (struct libc_ifunc_impl) { #impl, (void (*) (void)) impl, (usable) }; > + if (n < max) (array)[n++] = (struct libc_ifunc_impl) { #impl, (void (*) (void)) impl, (usable) }; > > /* Return the number of IFUNC implementations, N, for function FUNC if > string NAME matches FUNC. */ > -#define IFUNC_IMPL(n, name, func, ...) \ > +#define IFUNC_IMPL(max, name, func, ...) \ > if (strcmp (name, #func) == 0) \ > - { \ > + { size_t n = 0;\ > __VA_ARGS__; \ > return n; \ > } > diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c > index f6c6d008da285122cf3549efa5adf05d5e098680..4144615ab2198a97c76df40cec1056ea14300f56 100644 > --- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c > +++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c > @@ -24,16 +24,11 @@ > #include <init-arch.h> > #include <stdio.h> > > -/* Maximum number of IFUNC implementations. */ > -#define MAX_IFUNC 8 > - > size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - assert (max >= MAX_IFUNC); > - > - size_t i = 0; > + size_t i = max; > > INIT_ARCH (); > > @@ -76,5 +71,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > IFUNC_IMPL_ADD (array, i, strlen, !mte, __strlen_asimd) > IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_mte)) > > - return i; > + return 0; > } > diff --git a/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c b/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c > index af9f7490454673c87a251969f372545a80e36ced..e92bcb27a2535a20de958e384d623f1600591157 100644 > --- a/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c > +++ b/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c > @@ -29,7 +29,7 @@ size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - size_t i = 0; > + size_t i = max; > > bool use_neon = true; > #ifdef __ARM_NEON__ > @@ -57,5 +57,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > IFUNC_IMPL_ADD (array, i, memchr, use_neon, __memchr_neon) > IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_noneon)); > > - return i; > + return 0; > } > diff --git a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c b/sysdeps/i386/i686/multiarch/ifunc-impl-list.c > index c014f52bf942bba8ea929c0554ac97a78af8fbe5..9237b589f51f11aded6f83c370fd4c169f5eb5be 100644 > --- a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c > +++ b/sysdeps/i386/i686/multiarch/ifunc-impl-list.c > @@ -22,9 +22,6 @@ > #include <ifunc-impl-list.h> > #include "init-arch.h" > > -/* Maximum number of IFUNC implementations. */ > -#define MAX_IFUNC 4 > - > /* Fill ARRAY of MAX elements with IFUNC implementations for function > NAME and return the number of valid entries. */ > > @@ -32,9 +29,7 @@ size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - assert (max >= MAX_IFUNC); > - > - size_t i = 0; > + size_t i = max; > > /* Support sysdeps/i386/i686/multiarch/memchr.S. */ > IFUNC_IMPL (i, name, memchr, > @@ -358,5 +353,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32)) > #endif > > - return i; > + return 0; > } > diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c > index 01890367a4f078ee299eb94d6f7437baf3f882dd..e6ef5e6267a85e70b2f7c6c650a831a004d8e70d 100644 > --- a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c > +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c > @@ -22,16 +22,11 @@ > #include <ldsodefs.h> > #include <ifunc-impl-list.h> > > -/* Maximum number of IFUNC implementations. */ > -#define MAX_IFUNC 6 > - > size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - assert (max >= MAX_IFUNC); > - > - size_t i = 0; > + size_t i = max; > > unsigned long int hwcap = GLRO(dl_hwcap); > /* hwcap contains only the latest supported ISA, the code checks which is > @@ -179,5 +174,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > IFUNC_IMPL_ADD (array, i, strchr, 1, > __strchr_ppc)) > > - return i; > + return 0; > } > diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c > index ac533a98860687cffca0361fcc4281fd09390e9c..5a3c7a5886d25061b6ccd8ee7972a6c901f8e78e 100644 > --- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c > +++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c > @@ -22,16 +22,11 @@ > #include <ldsodefs.h> > #include <ifunc-impl-list.h> > > -/* Maximum number of IFUNC implementations. */ > -#define MAX_IFUNC 6 > - > size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - assert (max >= MAX_IFUNC); > - > - size_t i = 0; > + size_t i = max; > > unsigned long int hwcap = GLRO(dl_hwcap); > unsigned long int hwcap2 = GLRO(dl_hwcap2); > @@ -448,5 +443,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > IFUNC_IMPL_ADD (array, i, strcasestr, 1, > __strcasestr_ppc)) > > - return i; > + return 0; > } > diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c > index c1902b2c269cd4f41215a97879e947b4d1c03816..5d0c73094d127dad2bc2ba7ac1a2d339c41af948 100644 > --- a/sysdeps/s390/multiarch/ifunc-impl-list.c > +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c > @@ -66,9 +66,6 @@ > #include <ifunc-wmemset.h> > #include <ifunc-wmemcmp.h> > > -/* Maximum number of IFUNC implementations. */ > -#define MAX_IFUNC 3 > - > /* Fill ARRAY of MAX elements with IFUNC implementations for function > NAME supported on target machine and return the number of valid > entries. */ > @@ -76,9 +73,7 @@ size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - assert (max >= MAX_IFUNC); > - > - size_t i = 0; > + size_t i = max; > > /* Get hardware information. */ > unsigned long int dl_hwcap = GLRO (dl_hwcap); > @@ -670,5 +665,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > ) > #endif /* HAVE_WMEMCMP_IFUNC */ > > - return i; > + return 0; > } > diff --git a/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c b/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c > index 9be12f913077ddeabcb88c858ba47351fac1db7a..918eb69a032faa92a9b50889e173b6af7b3efcf3 100644 > --- a/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c > +++ b/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c > @@ -30,7 +30,7 @@ size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - size_t i = 0; > + size_t i = max; > int hwcap; > > hwcap = GLRO(dl_hwcap); > @@ -75,5 +75,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > __memmove_niagara7) > IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ultra1)); > > - return i; > + return 0; > } > diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c > index 7218095430a344bc2bb9e7038f96d3f89a4b5cba..8734294045348855e3b3109db93107f85413d5a9 100644 > --- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c > +++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c > @@ -23,9 +23,6 @@ > #include <sysdep.h> > #include "init-arch.h" > > -/* Maximum number of IFUNC implementations. */ > -#define MAX_IFUNC 5 > - > /* Fill ARRAY of MAX elements with IFUNC implementations for function > NAME supported on target machine and return the number of valid > entries. */ > @@ -34,9 +31,7 @@ size_t > __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > size_t max) > { > - assert (max >= MAX_IFUNC); > - > - size_t i = 0; > + size_t i = max; > > /* Support sysdeps/x86_64/multiarch/memcmpeq.c. */ > IFUNC_IMPL (i, name, __memcmpeq, > @@ -989,5 +984,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, > __wmemset_chk_avx512_unaligned)) > #endif > > - return i; > + return 0; > } >
diff --git a/include/ifunc-impl-list.h b/include/ifunc-impl-list.h index 78087f015ccce4172de3c537b9197cd3d6e199fd..00bf48f3f1e182dcd0862a40ac901ee954019d17 100644 --- a/include/ifunc-impl-list.h +++ b/include/ifunc-impl-list.h @@ -34,15 +34,15 @@ struct libc_ifunc_impl /* Add an IFUNC implementation, IMPL, for function FUNC, to ARRAY with USABLE at index I and advance I by one. */ -#define IFUNC_IMPL_ADD(array, i, func, usable, impl) \ +#define IFUNC_IMPL_ADD(array, max, func, usable, impl) \ extern __typeof (func) impl attribute_hidden; \ - (array)[i++] = (struct libc_ifunc_impl) { #impl, (void (*) (void)) impl, (usable) }; + if (n < max) (array)[n++] = (struct libc_ifunc_impl) { #impl, (void (*) (void)) impl, (usable) }; /* Return the number of IFUNC implementations, N, for function FUNC if string NAME matches FUNC. */ -#define IFUNC_IMPL(n, name, func, ...) \ +#define IFUNC_IMPL(max, name, func, ...) \ if (strcmp (name, #func) == 0) \ - { \ + { size_t n = 0;\ __VA_ARGS__; \ return n; \ } diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c index f6c6d008da285122cf3549efa5adf05d5e098680..4144615ab2198a97c76df40cec1056ea14300f56 100644 --- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c +++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c @@ -24,16 +24,11 @@ #include <init-arch.h> #include <stdio.h> -/* Maximum number of IFUNC implementations. */ -#define MAX_IFUNC 8 - size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - assert (max >= MAX_IFUNC); - - size_t i = 0; + size_t i = max; INIT_ARCH (); @@ -76,5 +71,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strlen, !mte, __strlen_asimd) IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_mte)) - return i; + return 0; } diff --git a/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c b/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c index af9f7490454673c87a251969f372545a80e36ced..e92bcb27a2535a20de958e384d623f1600591157 100644 --- a/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c +++ b/sysdeps/arm/armv7/multiarch/ifunc-impl-list.c @@ -29,7 +29,7 @@ size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - size_t i = 0; + size_t i = max; bool use_neon = true; #ifdef __ARM_NEON__ @@ -57,5 +57,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, memchr, use_neon, __memchr_neon) IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_noneon)); - return i; + return 0; } diff --git a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c b/sysdeps/i386/i686/multiarch/ifunc-impl-list.c index c014f52bf942bba8ea929c0554ac97a78af8fbe5..9237b589f51f11aded6f83c370fd4c169f5eb5be 100644 --- a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c +++ b/sysdeps/i386/i686/multiarch/ifunc-impl-list.c @@ -22,9 +22,6 @@ #include <ifunc-impl-list.h> #include "init-arch.h" -/* Maximum number of IFUNC implementations. */ -#define MAX_IFUNC 4 - /* Fill ARRAY of MAX elements with IFUNC implementations for function NAME and return the number of valid entries. */ @@ -32,9 +29,7 @@ size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - assert (max >= MAX_IFUNC); - - size_t i = 0; + size_t i = max; /* Support sysdeps/i386/i686/multiarch/memchr.S. */ IFUNC_IMPL (i, name, memchr, @@ -358,5 +353,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32)) #endif - return i; + return 0; } diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c index 01890367a4f078ee299eb94d6f7437baf3f882dd..e6ef5e6267a85e70b2f7c6c650a831a004d8e70d 100644 --- a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c @@ -22,16 +22,11 @@ #include <ldsodefs.h> #include <ifunc-impl-list.h> -/* Maximum number of IFUNC implementations. */ -#define MAX_IFUNC 6 - size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - assert (max >= MAX_IFUNC); - - size_t i = 0; + size_t i = max; unsigned long int hwcap = GLRO(dl_hwcap); /* hwcap contains only the latest supported ISA, the code checks which is @@ -179,5 +174,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ppc)) - return i; + return 0; } diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c index ac533a98860687cffca0361fcc4281fd09390e9c..5a3c7a5886d25061b6ccd8ee7972a6c901f8e78e 100644 --- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c @@ -22,16 +22,11 @@ #include <ldsodefs.h> #include <ifunc-impl-list.h> -/* Maximum number of IFUNC implementations. */ -#define MAX_IFUNC 6 - size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - assert (max >= MAX_IFUNC); - - size_t i = 0; + size_t i = max; unsigned long int hwcap = GLRO(dl_hwcap); unsigned long int hwcap2 = GLRO(dl_hwcap2); @@ -448,5 +443,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strcasestr, 1, __strcasestr_ppc)) - return i; + return 0; } diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c index c1902b2c269cd4f41215a97879e947b4d1c03816..5d0c73094d127dad2bc2ba7ac1a2d339c41af948 100644 --- a/sysdeps/s390/multiarch/ifunc-impl-list.c +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c @@ -66,9 +66,6 @@ #include <ifunc-wmemset.h> #include <ifunc-wmemcmp.h> -/* Maximum number of IFUNC implementations. */ -#define MAX_IFUNC 3 - /* Fill ARRAY of MAX elements with IFUNC implementations for function NAME supported on target machine and return the number of valid entries. */ @@ -76,9 +73,7 @@ size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - assert (max >= MAX_IFUNC); - - size_t i = 0; + size_t i = max; /* Get hardware information. */ unsigned long int dl_hwcap = GLRO (dl_hwcap); @@ -670,5 +665,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, ) #endif /* HAVE_WMEMCMP_IFUNC */ - return i; + return 0; } diff --git a/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c b/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c index 9be12f913077ddeabcb88c858ba47351fac1db7a..918eb69a032faa92a9b50889e173b6af7b3efcf3 100644 --- a/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c +++ b/sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c @@ -30,7 +30,7 @@ size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - size_t i = 0; + size_t i = max; int hwcap; hwcap = GLRO(dl_hwcap); @@ -75,5 +75,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __memmove_niagara7) IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ultra1)); - return i; + return 0; } diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c index 7218095430a344bc2bb9e7038f96d3f89a4b5cba..8734294045348855e3b3109db93107f85413d5a9 100644 --- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c +++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c @@ -23,9 +23,6 @@ #include <sysdep.h> #include "init-arch.h" -/* Maximum number of IFUNC implementations. */ -#define MAX_IFUNC 5 - /* Fill ARRAY of MAX elements with IFUNC implementations for function NAME supported on target machine and return the number of valid entries. */ @@ -34,9 +31,7 @@ size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t max) { - assert (max >= MAX_IFUNC); - - size_t i = 0; + size_t i = max; /* Support sysdeps/x86_64/multiarch/memcmpeq.c. */ IFUNC_IMPL (i, name, __memcmpeq, @@ -989,5 +984,5 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __wmemset_chk_avx512_unaligned)) #endif - return i; + return 0; }