diff mbox series

libquadmath: printf: fix misaligned access on args

Message ID 20240312190352.3455451-1-simon.chopin@canonical.com
State New
Headers show
Series libquadmath: printf: fix misaligned access on args | expand

Commit Message

Simon Chopin March 12, 2024, 7:03 p.m. UTC
On x86, this compiles into movdqa which segfaults on unaligned access.

This kind of failure has been seen when running against glibc 2.39,
which incidentally changed the printf implementation to move away from
alloca() for this data to instead append it at the end of an existing
"scratch buffer", with arbitrary alignement, whereas alloca() was
probably more likely to be naturally aligned.

Tested by adding the patch to the Ubuntu gcc-14 package in
https://launchpad.net/~schopin/+archive/ubuntu/libquadmath

Signed-off-by: Simon Chopin <simon.chopin@canonical.com>
---
 libquadmath/printf/printf_fp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


base-commit: 39737cdf002637c7a652e9c3e36f369cfce581e5

Comments

Florian Weimer April 2, 2024, 12:38 p.m. UTC | #1
* Simon Chopin:

> On x86, this compiles into movdqa which segfaults on unaligned access.
>
> This kind of failure has been seen when running against glibc 2.39,
> which incidentally changed the printf implementation to move away from
> alloca() for this data to instead append it at the end of an existing
> "scratch buffer", with arbitrary alignement, whereas alloca() was
> probably more likely to be naturally aligned.

This glibc change appears to be incorrect.  I think we need to preserve
ABI alignment for types than can be passed through the vararg interface.
I'm not sure if this easily possible, though.  Certainly needs a
discussion on libc-alpha.

Thanks,
Florian
diff mbox series

Patch

diff --git a/libquadmath/printf/printf_fp.c b/libquadmath/printf/printf_fp.c
index 8effcee88fa..d86aa650d38 100644
--- a/libquadmath/printf/printf_fp.c
+++ b/libquadmath/printf/printf_fp.c
@@ -363,7 +363,7 @@  __quadmath_printf_fp (struct __quadmath_printf_file *fp,
 
   /* Fetch the argument value.	*/
     {
-      fpnum = **(const __float128 **) args[0];
+      memcpy(&fpnum, *(void* const *) args[0], sizeof(fpnum));
 
       /* Check for special values: not a number or infinity.  */
       if (isnanq (fpnum))