On Fri, Dec 16 2022, Vincent Lefevre <vinc...@vinc17.net> wrote:
> On 2022-12-15 18:56:15 -0700, Theo de Raadt wrote:
>> There are almost no %n left in the software ecosystem.  If we are able
>> to make this crossing, everyone else is also capable, and eventually
>> will.  Just like with gets().
>
> FYI, this breaks GMP, whose configure script insists on %n being
> available, otherwise GMP uses its own, buggy implementation of
> vsnprintf, which triggers an assertion failure when %a/%A is used
> (and this bug affects MPFR). AFAIK, the GMP developers haven't
> reacted to the bug report sent in October.

https://gmplib.org/list-archives/gmp-bugs/2022-October/005200.html
Between the dubious antique check in acinclude.m4 and the bug in the
*printf reimplementation, this really sound like self-inflicted pain.
The diff below (against gmp-6.2.1) skips the %n test and is enough to
fix the misdetection.  Some tests need to stop using %n too.

Not an OpenBSD bug IMO, better discuss this with the GMP developers.


--- acinclude.m4.orig   Fri Dec 16 20:45:25 2022
+++ acinclude.m4        Fri Dec 16 20:51:48 2022
@@ -3664,9 +3664,9 @@ dnl  literal string is enough to provoke the problem, 
 dnl  needed.  There seems to be something weird going on with the optimizer
 dnl  or something, since on the first system adding a second check with
 dnl  "%n", or even just an initialized local variable, makes it work.  In
-dnl  any case, without bothering to get to the bottom of this, the two
-dnl  program runs in the code below end up successfully detecting the
-dnl  problem.
+dnl  any case, without bothering to get to the bottom of this, using %n is
+dnl  frowned upon on several modern systems.  So just assume that vsnprintf
+dnl  works if a simple test works...
 dnl
 dnl  glibc 2.0.x returns either -1 or bufsize-1 for an overflow (both seen,
 dnl  not sure which 2.0.x does which), but still puts the correct null
@@ -3682,7 +3682,6 @@ else
   AC_CACHE_CHECK([whether vsnprintf works],
                  gmp_cv_func_vsnprintf,
   [gmp_cv_func_vsnprintf=yes
-   for i in 'return check ("hello world");' 'int n; return check ("%nhello 
world", &n);'; do
      AC_TRY_RUN([
 #include <string.h>  /* for strcmp */
 #include <stdio.h>   /* for vsnprintf */
@@ -3713,13 +3712,12 @@ check (const char *fmt, ...)
 int
 main ()
 {
-$i
+   return check ("hello world");
 }
 ],
-      [:],
-      [gmp_cv_func_vsnprintf=no; break],
-      [gmp_cv_func_vsnprintf=probably; break])
-  done
+      [gmp_cv_func_vsnprintf=yes],
+      [gmp_cv_func_vsnprintf=no],
+      [gmp_cv_func_vsnprintf=probably])
   ])
   if test "$gmp_cv_func_vsnprintf" = probably; then
     AC_MSG_WARN([cannot check for properly working vsnprintf when cross 
compiling, will assume it's ok])

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to