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