[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Releasing groff 1.22.5?

From: Ingo Schwarze
Subject: Re: Releasing groff 1.22.5?
Date: Mon, 12 Oct 2020 18:08:27 +0200
User-agent: Mutt/1.12.2 (2019-09-21)


Bertrand Garrigues via wrote on Mon, Oct 12, 2020 at 01:42:49AM +0200:

> I've just pushed an update of the 'gnulib' and added this point
> to the 'FOR-RELEASE' file.

A major problem with gnulib emerged just now that we should perhaps
treat as a blocker.  I'm still gathering information about the
details, so please regard what i'm say here as a preliminary

The problem is not new with respect to groff nor with respect to
gnulib, but it is becoming more severe because several operating
systems strive to improve security with respect to printf(3).
OpenBSD developers have only been aware that that it affects
groff for a relatively short time.

The code in


line 4879 puts a format string containing a %n directive into
writeable memory and subsequently passes that memory as a first
argument to printf(3).

Using %n at all is insecure programming practice.  Having printf(3)
format strings in writeable memory (as opposed to in RODATA sections)
is slightly insecure programming practice.  Having %n in format strings
stored in writeable memory is highly insecure programming practice,
so much so that some operating systems already abort programs doing
that, most notably Mac OS X 10.13 or newer.  More operation systems
will soon start doing the same, for example OpenBSD, most likely next
week or so.

The way gnulib detects whether to compile that code seems to be
very broken.  On the one hand, gnulib performs extremely complex
tests that resemble an (overly aggressive) regression suite rather
than mere feature tests.  If i understand correctly, if *anything*
in that suite fails, no matter whether it's important or just a
very weird corner case, gnulib tends to compile the file
gnulib/lib/vasnprintf.c.  On the other hand, that file does lots
of very complicated version number and operating system name tests
on its own at compile time rather than at ./configure time, so it
is very difficult to figure out what is actually happening, and
even more so to check whether what is happening in a specific
compilation run is correct.

For example, it appears that one among large numbers of effects
that can trigger compilation of gnulib/lib/vasnprintf.c is that the
operating system denies %n in writeable memory, and as a consequence
gnulib/lib/vasnprintf.c is compiled and then proceeds to use %n in
writeable memory.

If i understand correctly, that is quite an absurd effect: the %n
feature ends up getting used precisely *because* it crashes the

Even if these specific issues could be solved, i would not feel
comfortable using gnulib/lib/vasnprintf.c.  It is about three times
the size of a reasonable printf(3) implementation, and it is riddled
with 552 preprocessor directive lines:

   $ grep '^#' gnulib/lib/vasnprintf.c  | sed 's/\# */\#/;s/ .*//' \
     | sort | uniq -c | sort -nr
 181 #endif
 170 #if
  71 #else
  60 #define
  30 #include
  22 #undef
  11 #ifndef
   7 #elif

So that 5621-line file, with a preprocessor directive every ten
lines on average, is practically impossible to audit for correctness,
even if one wanted to.

The ./bootstrap.conf in our root directory says:


While i did rarely run into operating systems that failed to provide
the non-standard function vasprintf(3) - a GNU extension also available
in all BSDs - groff does not use that function.  I do not remember
ever running into a system lacking any of the standard functions
 * fprintf(3) - first appeared in Version 7 AT&T UNIX
 * snprintf(3) and vsnprintf(3) - first in 4.4BSD

So my favourite solution would be to just stop using all the gnulib
*printf* modules.  I'm not aware of any portability problems they
might help to solve, not even on historic systems like Solaris 9,
but they most definitly cause severe portability and security issues
on several operating systems, in particular on modern ones.

What do you think?

Should i do testing without these three modules on OpenBSD, Linux,
and various versions of Solaris to see if that improves matters?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]