Asserts considered harmful (or GMP spills its sensitive information)

Jeffrey Walton noloader at gmail.com
Mon Dec 31 18:03:27 UTC 2018


The GMP library uses asserts to crash a program at runtime when
presented with data it did not expect. The library also ignores user
requests to remove asserts using Posix's -DNDEBUG. Posix asserts are a
deugging aide intended for developement, and using them in production
software ranges from questionable to insecure.

Many programs can safely use assert to crash a program at runtime.
However, the prequisite is, the program cannot handle sensitive
information like user passwords, user keys or sensitive documents.

High integrity software, like GMP and Nettle, cannot safely use an
assert to crash a program. To understand why the data flow must be
examined. First, when an assert fires, a SIGABRT is eventually sent to
the program on Unix and Linux
(http://pubs.opengroup.org/onlinepubs/009695399/functions/assert.html).

Second, the SIGABRT terminates the process and can write a core file.
This is the first point of unwanted data egress. Sensitive information
like user passwords and keys can be written to the filesystem
unprotected.

Third, the dump is sometimes sent to an error reporting service like
Apple Crash Report, Android Crash Report, Ubuntu Apport, and Windows
Error Reporting. This is the second point of unwanted data egress.
Sensitive information can be sent to the error reporting service. The
platform provider like Apple, Google, Microsoft and Ubuntu gain access
to the sensitive information, in addition to the developer.

In fact, when one popular security library used in Bitcoin wallets was
apprised of the situation, they responded:

    The standard abort() call also produces somewhat useful
    error messages on Windows, so I can get an idea on what’s
    going on when users report these.

Another popular security library used for code signing remarked:

    Please never ever define NDEBUG. This is a severe misfeature
    of the assert macro.

Wow, change your passwords and keys after an asert fires...

Here's a small example of triggering an assert using the Nettle
library. Nettle depends on GMP, and GMP is the root cause of the
information leak. The result below can be reporduced on i686, x86_64,
and Aarch64 using the attached script. ARM A-32 does not work at the
moment due to GMP build errors.

In the case below Nettle is using benign data and not maliciously
crafted data. Notice GMP spilled the sensitive information during a
sliding window modular exponentiation (also see
https://gmplib.org/repo/gmp-6.1/file/tip/mpn/generic/sec_powm.c).

# from Nettle 'make check'
...
PASS: rsa-keygen
PASS: rsa-sec-decrypt
sec_powm.c:293: GNU MP assertion failed: enb >= windowsize
../run-tests: line 57: 24756 Aborted (core dumped) "$1" $testflags
FAIL: rsa-compute-root
PASS: dsa
...
-------------- next part --------------
#!/usr/bin/env bash

CURR_DIR=$(pwd)
function finish {
  cd "$CURR_DIR"
}
trap finish EXIT

rm -rf /tmp/gmp-test

cd /tmp
wget --no-check-certificate https://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.bz2 -O gmp-6.1.2.tar.bz2
tar -xjf gmp-6.1.2.tar.bz2
cd gmp-6.1.2

PKG_CONFIG_PATH="/tmp/gmp-test/lib/pkgconfig" \
CPPFLAGS="-I/tmp/gmp-test/include -DNDEBUG" \
CFLAGS="-g2 -O2 -march=native -fPIC" \
LDFLAGS="-L/tmp/gmp-test/lib -Wl,-R,/tmp/gmp-test/lib -Wl,--enable-new-dtags" \
./configure --prefix=/tmp/gmp-test

make
make check
make install

cd /tmp
wget --no-check-certificate https://ftp.gnu.org/gnu/nettle/nettle-3.4.1.tar.gz -O nettle-3.4.1.tar.gz
tar -xzf nettle-3.4.1.tar.gz
cd nettle-3.4.1

PKG_CONFIG_PATH="/tmp/gmp-test/lib/pkgconfig" \
CPPFLAGS="-I/tmp/gmp-test/include -DNDEBUG" \
CFLAGS="-g2 -O2 -march=native -fPIC" \
LDFLAGS="-L/tmp/gmp-test/lib -Wl,-R,/tmp/gmp-test/lib -Wl,--enable-new-dtags" \
./configure --prefix=/tmp/gmp-test

make
make check
make install


More information about the gmp-bugs mailing list