bug-gnulib
[Top][All Lists]
Advanced

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

macOS 10.13 vasnprintf crash


From: comex
Subject: macOS 10.13 vasnprintf crash
Date: Fri, 7 Jul 2017 15:23:07 -0400

Hi,

In macOS 10.13 High Sierra (currently in beta), and presumably other
Apple OSes moving forward, the printf-family functions intentionally
crash if the format string contains %n and is located in writable
memory.  This is an exploit mitigation, similar to existing behavior
in glibc (with _FORTIFY_SOURCE=2) and Windows.

By default, gnulib's implementation of vasnprintf calls snprintf with
such format strings.  lib/vasnprintf.c has an explicit test for glibc
and Windows to avoid crashing there (relevant code copied below for
reference).  I suppose this test should either be extended to include
__APPLE__, or replaced with a configure-based test.  (There's an
existing test in m4/printf.m4 that checks whether %n works, including
with writable memory, but it doesn't seem to prevent vasnprintf from
triggering the crash.)

Thanks.

--

#if USE_SNPRINTF
# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) &&
!defined __UCLIBC__) ||      ((defined _WIN32 || defined __WIN32__) &&
! defined __CYGWIN__))
                fbp[1] = '%';
                fbp[2] = 'n';
                fbp[3] = '\0';
# else
                /* On glibc2 systems from glibc >= 2.3 - probably also older
                   ones - we know that snprintf's return value conforms to
                   ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
                   gl_SNPRINTF_TRUNCATION_C99 pass.
                   Therefore we can avoid using %n in this situation.
                   On glibc2 systems from 2004-10-18 or newer, the use of %n
                   in format strings in writable memory may crash the program
                   (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
                   in this situation.  */
                /* On native Windows systems (such as mingw), we can avoid using
                   %n because:
                     - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
                       snprintf does not write more than the specified number
                       of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
                       '4', '5', '6' into buf, not '4', '5', '\0'.)
                     - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
                       allows us to recognize the case of an insufficient
                       buffer size: it returns -1 in this case.
                   On native Windows systems (such as mingw) where the OS is
                   Windows Vista, the use of %n in format strings by default
                   crashes the program. See
                     <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and

<http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
                   So we should avoid %n in this situation.  */
                fbp[1] = '\0';
# endif
#else
                fbp[1] = '\0';
#endif



reply via email to

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