I was recently taking a look at the state of play regarding the security of
POSIX runtime linkers and was pointed at the QNX Neutrino RTOS to take a look.
In doing so I noticed a problem relating to the way that it handles
LD_DEBUG_OUTPUT which allows for the creation or overwriting of an arbitrary
file. Moreover the technique by which this can be achieved can be triggered
even where the binary being executed is setUID and is running as another user.
<mailto:timb (at) nth-dimension.org (dot) uk [email concealed]>
-----BEGIN PGP SIGNED MESSAGE-----
Nth Dimension Security Advisory (NDSA20110310)
Date: 10th March 2011
Author: Tim Brown <mailto:timb (at) nth-dimension.org (dot) uk [email concealed]>
URL: <http://www.nth-dimension.org.uk/> / <http://www.machine.org.uk/>
Product: QNX Neutrino RTOS 6.5.0 <http://www.qnx.com/products/neutrino-rtos/index.html>
The QNX Neutrino RTOS runtime linker allows the creation or overwriting
of an arbitrary file. Moreover the technique by which this can be
achieved can be triggered even where the binary being executed is setUID
and is running as another user.
Like glibc, the QNX Neutrino RTOS runtime linker supports the use of
the LD_DEBUG and LD_DEBUG_OUTPUT environment variables for debugging
purposes. These environment variables are trusted even where the binary
being executed is setUID and is running as the another user. It is
possible to create or overwrite an arbitrary file like so:
LD_DEBUG=all LD_DEBUG_OUTPUT=/pwned <setuid binary here>
If the file exists it will be overwritten with LD_DEBUG output and
existing permissions preserved however if as in the example above it
does not then a new file will be created, owned by root,nobody and
writable by both (assuming it was executed by the nobody user).
By default, the Neutrino runtime linker looks in /lib and then /usr/lib
for dependencies. So by locating a setUID binary that is using a library
from /usr/lib and creating one with the same name in /lib then the
newly created library will be used.
However, the Neutrino runtime linker won't write to /lib so it is
necessary to win a time of check, time of use race condition by creating
a symlink from the current working directory to the target library under
/lib hoping that the link will be added after the check has been made
that the value supplied for the LD_DEBUG_OUTPUT environment variable
does not point to /lib. After winning the race it is possible to copy
a malicious library over the newly created file writable file under /lib
and execute the target setUID binary again. This time it loads the
malicious library rather than the one in /usr/lib. This library abuses
.ctors to get triggered, sets the real UID to the effective UID and pops
Nth Dimension recommends that the vendor supplied patches should be
On 16th December 2010, Nth Dimension contacted the RIM to report the
described vulnerability affecting QNX Neutrino RTOS. from BlackBerry
Incident Response responded immediately to confirm that the report had
been received and forwarded to the relevant people at QNX.
Following on from this, Nth Dimension and the BlackBerry Incident Response
team exchanged messages and Nth Dimension supplied a PoC for the reported
On the 24th December 2010, BlackBerry Incident Response notified Nth
Dimension that the security team at QNX had assigned the flaw the internal
reference number PR84526 internally and begun investigations.
On the 11th February 2011, BlackBerry Incident Response notified Nth
Dimension that QNX intended to issue a fix on the 11th March 2011.
As of the 11th March 2011, the state of the vulnerabilities is believed
to be as follows. A fix has been made available by QNX which it is
believed successfully resolved the reported issue. This patch has not
however been tested by Nth Dimension preventing us confirming that fact.
Nth Dimension would like to thank all the security folk at RIM, in
particular the BlackBerry Incident Response team for the way they worked
to resolve the issue.