Asia-18-Wetzels Abassi Dissecting QNX WP PDF
Asia-18-Wetzels Abassi Dissecting QNX WP PDF
Asia-18-Wetzels Abassi Dissecting QNX WP PDF
T
his work concerns a dissection of QNX: a pro- addition, it is deployed in highly sensitive embedded
prietary, real-time operating system aimed systems such as industrial automation PLCs, medical
at the embedded market. QNX is used in devices, building management systems, railway
many sensitive and critical devices in different in- safety equipment, Unmanned Aerial Vehicles (UAVs),
dustry verticals and while some prior security re- anti-tank weapons guidance systems, the Harris
search has discussed QNX, mainly as a byproduct Falcon III military radios, Caterpillar mining control
of BlackBerry mobile research, there is no prior systems, General Electric turbine control systems and
work on QNX exploit mitigations and secure ran- Westinghouse and AECL nuclear powerplants.
dom number generators. In this work, carried out
as part of the master’s thesis of the first author, we The interest of high-profile actors in QNX-based
present the first reverse-engineering and analysis systems is evidenced by a series of documents from
of the exploit mitigations, secure random number the United States Central Intelligence Agency (CIA)
generators and memory management internals of obtained and released by WikiLeaks under the name
QNX versions up to and including QNX 6.6 and the ’Vault 7’. These documents show an interest on part
brand new 64-bit QNX 7.0 released in March 2017. of the CIA’s Embedded Development Branch (EDB) of
We uncover a variety of design issues and vulnera- the Engineering Development Group (EDG) (which
bilities which have significant implications for the develops and tests exploits and malware used in covert
exploitability of memory corruption vulnerabilities operations) in targeting QNX [65].
on QNX as well as the strength of its cryptographic
ecosystem. In this work, we focus primarily on QNX’s ’binary
security’ ie. its hardening against memory corruption
exploitation, as well as the quality of its secure random
1 Introduction number generators.
More precisely, this work makes the following novel
QNX [17] is a proprietary, closed-source, Unix-like contributions:
real-time operating system with POSIX support aimed
primarily at the embedded market. Initially released
in 1982 for the Intel 8088 and later acquired by • It presents the first reverse-engineering of the
BlackBerry, it forms the basis of BlackBerry OS, proprietary, closed-source QNX OS to document
BlackBerry Tablet OS and BlackBerry 10 used in the internals of its memory manager, exploit
mobile devices as well as forming the basis of Cisco’s mitigations (eg. NX memory, ASLR, stack canaries,
IOS-XR used in carrier-grade routers such as the RELRO) and secure random number generators
CRS, the 12000 and the ASR9000 series. QNX also (both the kernel PRNG and /dev/random),
dominates the automotive market [61] (particularly covering all QNX versions as of writing (ie. ≤ 6.6
telematics, infotainment and navigation systems) and and the newly released QNX 7.0).
is found in millions of cars from Audi, Toyota, BMW,
Porsche, Honda and Ford to Jaguar and Lincoln. In • It presents the first analysis of the exploit
Dissecting QNX
mitigations and secure RNGs on QNX ≤ 6.6 and for hundreds of POSIX utilities, common networking
7.0 and uncovers a variety of design issues and technologies (IPv4/IPv6, IPSec, FTP, HTTP, SSH,
vulnerabilities which have significant implications etc.) and dynamic libraries. As opposed to the
for the exploitability of memory corruption monolithic kernel architecture of most general-purpose
vulnerabilities on QNX as well as the strength of OSes, QNX features a microkernel which provides
its cryptographic ecosystem. minimal services (eg. system call and interrupt
handling, task scheduling, IPC message-passing, etc.)
• As a result of this work, we disclosed the un- to the rest of the operating system which runs as
covered issues to the vendor and cooperated in a team of cooperating processes as illustrated in
drafting patches to help protect system end-users. Figure 1. As a result, only the microkernel resides
in kernelspace with the rest of the operating system
and other typical kernel-level functionality (drivers,
Given that there is, as discussed in Section 2.1, protocol stacks, etc.) residing in userspace next to
no prior work on QNX’s mitigations, secure ran- regular user applications albeit separated by privilege
dom number generators or memory management boundaries. In QNX the microkernel is combined with
internals, we consider this work a significant con- the process manager in a single executable module
tribution to the state of the art in understanding called procnto. QNX libc converts POSIX function
QNX security as well as QNX OS internals more broadly. calls into message handling functions which pass
messages through the microkernel to the relevant pro-
In Section 2 we present an brief overview of QNX’s cess. As of writing, the latest QNX release is version 7.0.
OS architecture, its security architecture and its mem-
ory management internals. We discuss the result of our
reverse-engineering and analysis of the exploit mitiga-
tions of QNX versions up to and including 6.6 in Section Process
M anager
PS File
M anager H FS File
U DF File
M anager
N FS File
M anager Flash File
M anager
3 and those of QNX version 7.0 in Section 4. In Section
M anager
Q N X N eutrino
5 we present the results of our reverse-engineering and M icrokernel
Page 2 of 22
Dissecting QNX
their own root processes in userspace next to non-OS U ser Process 1 U ser Process 2 U ser Process 3 System Process
processes. Separation between OS processes and
non-OS processes comes down to a combination procnto
of enforcement of user permissions and additional
sandboxing capabilities [54]. If a non-OS process
is run as root, the only way to wall it off from the 0 3.5G 0 3.5G 0 3.5G 3.5G 4G
wider OS is by restricting its capabilities. On the other
hand, capabilities can be assigned on a granular level Figure 2: QNX Private Virtual Memory [53]
allowing or disallowing access to system actions and
resources meaning for many processes there is no need
to run as root to perform their functionality. Security
separation between userspace and kernelspace is
also mediated in this fashion which does mean, Architecture Start End
however, that there is no ’absolute isolation’ of the Userspace
microkernel and a root user without significant x86 0x00000000 0xBFFFFFFF
capability restrictions (as is the default for most OS AArch32 0x00000000 0x7FFFFFFF
processes) can easily pivot into the microkernel by MIPS 0x00000000 0x7FFFFFFF
means of common kernel calls, access to sensitive PPC 0x40000000 0xFFFB0000
devices (eg. /dev/mem) or installation of Interrupt SuperH 0x00000000 0x7BFF0000
Service Routines (ISRs). Kernelspace
x86 0xC0000000 0xFFFFFFFF
As such one should not confuse the safety guarantee AArch32 0x80000000 0xFFFFFFFF
that the crashing of one component does not lead to MIPS 0x80000000 0xFFFFFFFF
a crash of the entire system with a security guarantee PPC 0x00000000 0x3FFFFFFF
that the compromise of one component could not lead SuperH 0x80000000 0xCFFFFFFF
to the compromise of the entire system. If no explicit
capability restrictions are put in place by system inte- Table 1: QNX ≤ 6.6 Address Boundaries
grators, nothing prevents a compromise of a process
with the right privileges or capabilities from leading to
arbitrary kernelspace code execution. Architecture Start End
Userspace
x86 0x00000000 0xBFFFFFFF
2.4 Memory Management x86-64 0x00000000 0x0000007FFFFFFFFF
QNX offers a full-protection memory model placing AArch32 0x00000000 0x7FFFFFFF
each process within its own private virtual memory by AArch64 0x00000000 0x0000007FFFFFFFFF
utilizing the MMU as shown in Figure 2. On QNX every Kernelspace
process is created with at least one main thread (with x86 0xC0000000 0xFFFFFFFF
its own, OS-supplied stack) and any subsequently x86-64 0x0000008000000000 0xFFFFFFFFFFFFFFFF
created thread can either be given a customly allocated AArch32 0x80000000 0xFFFFFFFF
stack by the program or a (default) system-allocated AArch64 0x0000008000000000 0xFFFFFFFFFFFFFFFF
stack for that thread. QNX’s virtual memory provides
permission capabilities and the memory manager Table 2: QNX 7.0 Address Boundaries
ensures inter-process memory access is mediated
by privilege as well as capability checks [54]. QNX
handles typical memory objects such as stacks, the Architecture Libc Addr.
heap, object memory (eg. video card memory mapped QNX ≤ 6.6
into userspace), shared libraries, etc. and has support x86 0xB0300000
for shared- and typed memory [57, 59]. The relevant AArch32 0x01000000
memory manager internals are described in detail in MIPS 0x70300000
Section 3.2. PPC 0xFE300000
SuperH 0x70300000
For QNX versions up to and including 7.0, we illus- QNX 7.0
trate QNX user- and kernel-space address boundaries, x86 0xB0300000
derived from reverse-engineering, in Tables 1 and 2. x86-64 0x0000000100000000
On QNX systems where ASLR is not enabled, libc AArch32 0x01000000
is loaded by default at the addresses illustrated in AArch64 0x0000000100000000
Table 3. For QNX versions up to and including 6.6
on x86, the default user- and kernel-space layouts Table 3: QNX Default Libc Load Addresses
when ASLR is disabled are illustrated in Figures 3 and 4
Page 3 of 22
Dissecting QNX
normal kernel
mapping OR We disclosed all discovered issues to the vendor and
4m pagetable as a result fixes and improvements based on our sug-
for kernel code gestions were included in QNX 7.0 as documented in
& data
0xF0000000 Section ??.
first 256M of
phys. mem
0xE0000000 3.1 Executable Space Protection
normal kernel
mapping Executable Space Protection (ESP), also referred
0xD0400000 to as Data Execution Prevention (DEP), NX memory
temp. map to
zero L2 or WˆX memory, is a mitigation that seeks to prevent
pagetables 0xD0000000 attackers from executing arbitrary injected payloads
through a Harvard-style code and data memory
message pass
temp. map separation on Von Neumann processors by rendering
0xC0000000
data memory non-executable and ensuring code
memory is non-writable. ESP can be implemented by
Figure 4: QNX ≤ 6.6 Kernelspace Memory Layout (x86) either relying on hardware support (eg. the x86 NX
bit or ARM XN bit) or by means of software emulation.
QNX has support for hardware-facilitated ESP among
3 QNX ≤ 6.6 Exploit Mitigations most of the architectures which support it since version
6.3.2 as shown in Table 5.
In this section we will present the results of our
reverse-engineering and subsequent analysis of Insecure ESP Default Policy (CVE-2017-XXXX):
QNX’s exploit mitigations and secure random number While QNX supports ESP for several architectures, its
Page 4 of 22
Dissecting QNX
Architecture Support memory objects (eg. code, stack, heap, etc.) and
x86 X(requires PAE on IA-32e) rendering them hard to guess.
ARM X
MIPS × QNX has ASLR support since version 6.5 (not
PPC 400 X supported for QNX Neutrino RTOS Safe Kernel 1.0)
PPC 600 X but it’s disabled by default. QNX ASLR can be enabled
PPC 900 X on a system-wide basis by starting the procnto
microkernel with the -mr option [55] and disabled
Table 5: QNX ≤ 6.6 Hardware ESP Support with the -m∼r option. A QNX child process normally
inherits its parent’s ASLR setting but as of QNX 6.6
ASLR can also be enabled or disabled on a per-process
implementation is dangerously weakened due to inse- basis by using the on utility [51] (with the -ae and -ad
cure default settings. As a result, the stack (but not the options respectively). Alternatively, one can use the
heap) is always executable regardless of the presence SPAWN_ASLR_INVERT or POSIX_SPAWN_ASLR_INVERT
of hardware ESP support. As the documentation [55] flags with the spawn and posix_spawn process
states, the QNX microkernel, and process manager exe- spawning calls. To determine whether or not a process
cutable (procnto) has a memory management startup is using ASLR, one can use the DCMD_PROC_INFO [49]
option relating to stack executability (available as of command with the devctl [50] device control call
QNX 6.4.0 or later): and test for the _NTO_PF_ASLR bit in the flags member
of the procfs_info structure.
• -mx: (Default) Enable the PROT_EXEC flag for
system-allocated threads (the default). This As shown in Table 6, QNX ASLR randomizes the base
option allows gcc to generate code on the stack - addresses of userspace and kernelspace stack, heap
which it does when taking the address of a nested and mmap’ed addresses as well as those of userspace
function (a GCC extension). shared objects (eg. loaded libraries) and the executable
image (if the binary is compiled with PIE [16]). It does
• -m˜x: Turn off PROT_EXEC for system-allocated not, however, have so-called KASLR support in order
stacks, which increases security but disallows tak- to randomize the kernel image base address. The QNX
ing the address of nested functions. You can Momentics Tool Suite development environment (as
still do this on a case-by-case basis by doing an of version 5.0.1, SDP 6.6) does not have PIE enabled
mprotect() call that turns on PROT_EXEC for the by default and indeed after an evaluation with a
required stacks. customized version of the checksec [34] utility we
found that none of the system binaries (eg. those in
Since the first option is the default, any QNX system
/bin, /boot, /sbin directories) are PIE binaries in a
which starts procnto without explicit -m˜x settings
default installation.
will have an executable stack, regardless of hardware
ESP support or individual binary GNU_STACK [35] set-
tings. The rationale behind this decision seems to have Memory Object Randomized
been a desire for backwards compatibility with binaries Userspace
which require executable stacks which has caused sim- Stack X
ilar issues on Linux in the past [33]. This backwards Heap X
compatibility is enforced on a system-wide (rather than Executable Image X
on an opt-out, per-binary basis) as confirmed by the Shared Objects X
fact that the QNX program loader does not parse the mmap X
GNU_STACK header of binaries. The problem with the Kernelspace
QNX approach here is that this setting is applied on a Stack X
system-wide basis and has an insecure default, putting Heap X
the secure configuration burden on system integrators. Kernel Image ×
mmap X
3.2 Address Space Layout Randomiza-
Table 6: QNX ≤ 6.6 ASLR Memory Object Randomization Sup-
tion port
When developing exploits, attackers rely on knowledge
of the target application’s memory map for directing We reverse-engineered QNX’s ASLR implementation
write and read operations as well as crafting code-reuse (as illustrated in Figure 5) and found that it is
payloads. Address Space Layout Randomization ultimately implemented in two function residing in
(ASLR) [31] is a technique which seeks to break the microkernel: stack_randomize and map_find_va
this assumption by ensuring memory layout secrecy (called as part of mmap calls). QNX uses the Executable
via randomization of addresses belonging to various and Linking Format (ELF) binary format and pro-
Page 5 of 22
Dissecting QNX
i f ( f l a g s & ( MAP_FIXED|IMAP_GLOBAL) ) {
thread_specret dlopen
...
} else {
stack_randomize _heap_alloc load_object
r e p l −> f i r s t = NULL ;
memmgr.mmap
va = map_find_va (mh, va , s i z e ,
mask , f l a g s ) ;
vmm_map init_objects
i f ( va == VA_INVALID ) {
r = ENOMEM;
ClockCycles map_find_va kernel heap kernel stack(s)
goto f a i l 1 ;
}
Kernelspace
ASLR }
Page 6 of 22
Dissecting QNX
Page 7 of 22
Dissecting QNX
In order to demonstrate this, we evaluated the value is not considered secret and in fact it leaks ev-
entropic quality of QNX ASLR randomized addresses erywhere (both to local users as well as via network
of several userspace memory objects. We did this with services). As a result, an attacker in posession of the
a script starting 3000 ASLR-enabled PIE processes per current clock cycle counter value could reconstruct the
boot session and running 10 boot sessions, collecting clock cycle counter value (in a fashion analogous to the
30000 samples per memory object in total. We used work in [36]) at the time of memory object random-
the NIST SP800-90B [41] Entropy Source Testing (EST) ization. Given the current clock cycle counter value
tool [38] in order to evaluate the entropic quality and an estimate on memory object initialization times,
of the address samples by means of a min entropy an attacker can deduce the clock cycle counter value
estimate, illustrated in Table 8. Min entropy is a at randomization time for a given memory object and
conservative way of measuring the (un)predictability reconstruct it as:
of a random variable X and expresses the number of
(nearly) uniform bits contained in X , with 256 bits of
uniformly random data corresponding to 256 bits of clockt = clockc − ((timec − timet ) ∗ cycless )
min entropy.
where clockt , clockc , timet and timec are the target
and current clock cycle counter and timestamp values
Memory Object Min Entropy (8 bits per symbol) and cycless is the number of cycle increments per
Stack 1.59986 second.
Heap 1.00914
Executable Image 0.956793 procfs Infoleak (CVE-2017-3892): The proc
Shared Objects 0.905646 filesystem (procfs) is a pseudo-filesystem on Unix-
like operating systems that contains information
Table 8: QNX 6.6 ASLR Userspace Memory Object Min Entropy
about running processes and other system aspects
via a hierarchical file-like structure. This exposure
From Table 8 we can see that, on average, a QNX of process information often includes ASLR-sensitive
randomized userspace memory object has a min information (eg. memory layout maps, individual
entropy of 1.11785975. This means that it has a little pointers, etc.) and as such has a history as a source for
more than 1 bit of min entropy per 8 bits of data. If we local ASLR infoleaks [12, 44, 62] with both GrSecurity
extrapolate this to the full 32 bits of a given address and mainline Linux [26, 64] seeking to address
this means that the stack, heap, executable image procfs as an infoleak source. On QNX procfs [48]
and shared object base addresses have min entropy is implemented by the process manager component
values of 6.39944, 4.03656, 3.827172 and 3.622584 of procnto and provides the following elements for
respectively, with an average of 4.471439 bits of min each running process:
entropy. This compares very unfavorably with the
entropy measurements for various Linux-oriented
ASLR mechanisms in [7]. • cmdline: Process command-line arguments.
• exefile: Executable path.
On QNX, as is the case with many operating systems, • as: The virtual address space of the target process
child processes inherit the memory layout of parent mapped as a pseudo-file.
processes. As a result when attacking forked or
pre-forked applications an attacker can guess an ASLR These procfs entries can be interacted with like files
address, after which the target child crashes and is and subsequently manipulated using the devctl [50]
restarted with an identical memory layout allowing API to operate on a file-descriptor resulting from
the attacker to make another guess and so on. This opening a procfs PID entry. Since process entries
facilitates both brute-force attacks and malicious child in QNX’s procfs are world-readable by default, this
processes attacking siblings in Android Zygote-style means a wide range of devctl-based information
models [23]. Given this memory layout inheritance, retrieval about any process is available to users
the fact that QNX ASLR provides only limited entropy regardless of privilege boundaries. For example, the
and has no active relocation (ie. memory object QNX pidin [52] utility, which makes use of procfs
locations are never re-randomized), QNX ASLR is to provide a wide range of process inspection and
highly susceptible to brute-force attacks. debugging options, easily allows any user to obtain
stackframe backtraces, full memory mappings and
Finally it should be noted that ClockCycles is not program states for any process. This effectively
a secure random number generator and by drawing di- constitutes a system-wide local information leak
rectly from its output the clock cycle counter value acts allowing attackers to circumvent ASLR. It should be
analogous to a random number generator’s internal noted this issue is not due to the availability of any
state. Contrary to a secure random number genera- particular utility (such as pidin) but rather results
tor’s internal state, however, the clock cycle counter from a fundamental lack of privilege enforcement on
Page 8 of 22
Dissecting QNX
LD_DEBUG Infoleak (CVE-2017-9369): The QNX’s QCC implements the GCC SSP scheme [43]
LD_DEBUG [37] environment variable is used on some and supports all the usual SSP flags (strong, all, etc.).
Unix-like systems to instruct the dynamic linker to Since the compiler-side of the QNX SSP implementa-
output debug information during execution. On tion is identical to the regular GCC implementation,
QNX there are no cross-privilege restrictions on this the master canary is stored accordingly and canary
environment variable, leading to a (local) information violation invokes the __stack_chk_fail handler.
leak that can be used to circumvent ASLR. Since there
are no privilege checks (akin to the ’secure-execution Insecure User Canary Generation (CVE-2017-
mode’ [63] offered by some Linux distributions) on XXXX): For userspace applications, this handler is
this environment variable, a local attacker can execute implemented in QNX’s libc. On the OS-side, reverse-
setuid binaries with higher privileges using dynamic engineering of libc shows us that violation handler
linker debugging settings (eg. LD_DEBUG=all) in (shown in cleaned-up form in Listing 5) is a wrapper
order to output sensitive information (eg. memory for a custom function called _ssp_fail which writes
layout, pointers, etc.). This issue is similar to CVE- an alert message to the /dev/tty device and raises
2004-1453 [22] affecting certain versions of GNU glibc. a SIGABRT signal. QNX generates its master canary
value once upon program startup (during loading of
ASLR Correlation Attack (CVE-2017-3892): libc) and it is not renewed at any time. Instead of the
ASLR randomization of memory object base addresses regular libssp function __guard_setup, QNX uses a
can prove to be insufficient if different memory objects custom function called __init_cookies (shown in
are correlated. In such a case an attacker in the Listing 6) invoked by the _init_libc routine in order
posession of one address can determine the location to (among other things) generate the master canary
of others by means of applying a static (or minimally value.
varying) offset, rendering even the most limited
information leaks very powerful.
Listing 5: QNX 6.6 Stack Canary Failure Handler (Userspace)
During our evaluation we found a partial correla- void _ _ s t a c k _ c h k _ f a i l ( void )
tion attack on QNX’s ASLR implementation, affecting {
both PIE and non-PIE binaries. The offset from the pro- i f ( ( f d = open ( " / dev / t t y " , 1) ) != −1)
gram image base to the base address of the first loaded w r i t e ( fd , " *** s t a c k smashing
shared library (libc) is of the mask form 0x00FFF000 d e t e c t e d *** " ) ;
with at most 12 bits being randomized. We evaluated r a i s e ( SIGABRT ) ;
the entropic quality of this offset value in order to deter- }
mine the feasibility of correlation attacks by collecting
300 offset samples per boot session and running 10 Listing 6: QNX 6.6 Userspace Canary Generation
boot sessions, making for 3000 samples total. Using
void _ i n i t _ c o o k i e s ( void )
the NIST Entropy Source Testing (EST) tool [38] we
{
determined the min entropy of these offset values to
void * s t a c k v a l ;
be 0.918311, making for less than 1 bit of min entropy
per 8 bits of data, which corresponds to 1.3774665 ts0 = ( ClockCycles () & 0 x f f f f f f f f ) ;
bits of min entropy for the 12 affected variable bits can0 = ( t s 0 ^ (((& s t a c k v a l ) ^ (
in the offset. Given that this is well below an exhaus- _ i n i t _ c o o k i e s ) ) >> 8) ) ;
tive search, this makes a variation of the offset2lib [6] _ s t a c k _ c h k _ g u a r d = can0 ;
attack feasible.
ts1 = ( ClockCycles () & 0 x f f f f f f f f ) ;
can1 = (((& s t a c k v a l ) ^ can0 ) >> 8) ;
3.3 Stack Smashing Protector _ a t e x i t _ l i s t _ c o o k i e = ( can1 ^ t s 1 ) ;
Stack Smashing Protector (SSP) [43] is a so-called
ts2 = ( ClockCycles () & 0 x f f f f f f f f ) ;
stack canary scheme which seeks to prevent the _ a t q e x i t _ l i s t _ c o o k i e = ( can1 ^ t s 2 ) ;
exploitation of stack buffer overflows by inserting
a secret and unpredictably random canary value in _ s t a c k _ c h k _ g u a r d &= 0 x f f 0 0 f f f f ;
between the local stack variables and the stackframe }
metadata (eg. saved return address, saved frame
pointer). Any attempt at stack smashing which seeks As shown in Listing 6, QNX canaries have a
to overwrite such metadata also ends up corrupting terminator-style NULL-byte in the middle and are
the canary value which is, upon function return, generated using a custom randomization routine
compared against the original master value so that (slightly resembling the "poor man’s randomization
when a mismatch is detected the SSP will invoke a patch" included in some Linux distributions for
Page 9 of 22
Dissecting QNX
performance purposes [28, 29]) rather than drawing it Settings Min Entropy (8 bits per symbol)
from a secure random number generator. The custom No ASLR 1.94739
randomization routine draws upon three sources: ASLR, no PIE 1.94756
ASLR + PIE 1.94741
• _init_cookies: This is the function’s own address Table 9: QNX 6.6 Stack Canary Min Entropy
and as such, the only randomization it introduces
is derived from ASLR’s effect on shared library
On top of entropy issues, ClockCycles is not a
base addresses which means that if ASLR is
secure random number generator, as we discussed
disabled (or circumvented) this is a static value.
before with ASLR, and as such similar reconstruction
attacks could be mounted against QNX canaries.
• stackval: This is an offset to the current stack
pointer and as such, the only randomization it
Absent Kernel Canary Generation (CVE-2017-
introduces is derived from ASLR’s effect on the
XXXX): When it comes to kernelspace stack canary
stack base which means that if ASLR is disabled
protection, the QNX microkernel (in the form of the
(or circumvented) this is simply a static value.
procnto process) also features an SSP implemen-
tation covering a subset of its functions. Since the
• ClockCycles: The lower 32 bits of the result of
kernel neither loads nor is linked against libc (and
a ClockCycles() call are used to construct the
canary violations need to be handled differently), SSP
master canary value.
functionality is implemented in a custom fashion here.
Reverse-engineering of the microkernel showed that it
Since it includes a terminator-style NULL-byte, the
has a custom __stack_chk_fail handler (illustrated
QNX master canary value has a theoretical upper limit
in Listing 7) but no master canary initialization routine.
of 24 bits of entropy. However, all entropy in QNX
As a result, QNX never actually initializes the kernel
stack canaries is ultimately based on invocations of
master canary value and hence its value is completely
the ClockCycles kernel call. If ASLR is enabled,
static and known to the attacker (0x00000000),
the stackval address gets randomized when the
rendering QNX kernel stack canary protection trivial
main thread is spawned during program startup and
to bypass.
the _init_cookies address gets randomized when
libc gets loaded by the runtime linker. The ts0
value is generated when _init_cookies is called by Listing 7: QNX 6.6 Stack Canary Failure Handler (Ker-
_init_libc which is invoked upon application startup nelspace)
(but after libc is loaded). void _ _ s t a c k _ c h k _ f a i l ( void )
{
The first problem with using ClockCycles as a k p r i n t f ( " *** s t a c k smashing d e t e c t e d
source of randomness is the limited entropy provided i n p r o c n t o *** " ) ;
and thus the degree to which the canary is unpre- __asm{ i n t 0x22 } ;
dictable and the size of the search space. In order }
to evaluate the entropic quality of QNX’s canary
generation mechanism, we collected canary values
for three different process configurations: No ASLR, 3.4 Relocation Read-Only
ASLR but no PIE and ASLR with PIE. We used a
script starting 785 instances of each configuration per QNX supports Relocation Read-Only (RELRO), a
boot session and repeated this for 10 boot sessions, mitigation that allows for marking relocation sections
collecting 7850 samples per configuration in total. as read-only after they have been resolved in order to
We then used the NIST Entropy Source Testing (EST) prevent attackers from using memory corruption flaws
tool [38] in order to obtain min entropy estimates to modify relocation-related information (such as Pro-
for the sample sets as illustrated in Table 9. Based cedure Linkage Table (PLT) related Global Offset
on these observations we can conclude that a) QNX Table (GOT) entries using GOT-overwriting [20]).
canary entropy is far less than the hypothetical upper RELRO comes in two variants: partial and full, with
bound of 24 bits, being on average 7.78981332 bits for the former protecting non-PLT entries and the latter
a 32-bit canary value and b) ASLR plays no significant protecting the entire GOT. RELRO is implemented
contributing role to the overall QNX canary entropy. partially in the toolchain and partially in the operating
system.
Due to the absence of any canary renewal func-
tionality [5], regular as well as byte-for-byte [67] In most RELRO implementations, the compiler first
brute-force attacks are feasible against QNX, especially stores constants requiring dynamic relocation in a
considering the low entropic quality of the canaries. dedicated section (typically named .data.rel.ro)
before the linker creates a PT_GNU_RELRO program
Page 10 of 22
Dissecting QNX
Page 11 of 22
Dissecting QNX
i f ( s i z e _ v a l != obj−>s i z e )
GNU_STACK ELF header is not parsed. {
randomized_addr = ( obj−>addr + (
random_value ( ) << 12) % ( obj−>
4.2 Address Space Layout Randomiza- size − size_val )) & 0
tion xFFFFFFFFFFFFF000 ;
}
QNX 7 ASLR remains disabled by default and does
not provide KASLR support for kernel image base ...
randomization. }
Page 12 of 22
Dissecting QNX
Page 13 of 22
Dissecting QNX
Page 14 of 22
Dissecting QNX
is drawn from the PRNG (which means it is also done before reseeding the state from the entropy pool
constantly called during entropy accumulation thus potentially allowing for low-quality entropy to
due to the above mentioned output mixing determine the entire state.
mechanism). In both cases, a permutation named
IncGaloisCounter5X32 is applied to the entropy In order to evaluate the QNX Yarrow PRNG output
pool before the pool contents are mixed into quality we used two test suites: DieHarder [18]
a SHA1 state which eventually becomes the and the NIST SP800-22 [40] Statistical Test
Yarrow internal state. Contrary to Yarrow design Suite (STS) [39]. DieHarder is a random number
specifications, no entropy quality estimation is generator testing suite, composed of a series of
done before reseeding. statistical tests, "designed to permit one to push a weak
generator to unambiguous failure" [18]. The NIST
Listing 15: QNX 6.6 yarrow_do_sha1 function Statistical Test Suite (STS) consists of 15 tests
void yarrow_do_sha1 ( yarrow_t * p , developed to evaluate the ’randomness’ of binary
yarrow_gen_ctx_t * ctx ) sequences produced by hardware- or software-based
{ cryptographic (pseudo-) random number generators
SHA1Init (& sha ) ; by assessing the presence or absence of a particular
statistical pattern. The goal is to "minimize the
I n c G a l o i s C o u n t e r 5 X 3 2 ( p−>pool . s t a t e )
;
probability of accepting a sequence being produced by
sha . s t a t e [ 0] ^= p−>pool . s t a t e [ 4 ] ; a generator as good when the generator was actually
sha . s t a t e [ 1] ^= p−>pool . s t a t e [ 3 ] ; bad" [40]. While there are an infinite number of
sha . s t a t e [ 2] ^= p−>pool . s t a t e [ 2 ] ; possible statistical tests and as such no specific test
sha . s t a t e [ 3] ^= p−>pool . s t a t e [ 1 ] ; suite can be deemed truly complete, they can help
sha . s t a t e [ 4] ^= p−>pool . s t a t e [ 0 ] ; uncover particularly weak random number generators.
SHA1Update(&sha , c t x−>i v , 20) ; QNX Yarrow passed both the DieHarder and
SHA1Update(&sha , c t x−>out , 20) ; NIST STS tests but this only tells us something about
SHA1Final ( c t x−>out , &sha ) ;
the quality of PRNG output, leaving the possibility
}
open that raw noise / source entropy is (heavily)
biased which can result in predictable PRNG outputs
Listing 16: QNX 6.6 yarrow_make_new_state function as well as attackers being able to replicate PRNG
void yarrow_make_new_state ( yarrow_t * internal states after a reasonable number of guesses.
p , yarrow_gen_ctx_t * ctx , uint8_t As such we reverse-engineered and evaluated the QNX
* state ) random service’s boot- and runtime entropy sources.
{
f o r ( i = 0 ; i < 20; i++) Boottime Entropy Analysis: When random is ini-
c t x−>i v [ i ] ^= s t a t e tialized it gathers initial boottime entropy from the
following sources (as illustrated in Figure 9) which are
SHA1Init (& sha ) ;
fed to the SHA1 hash function to produce a digest used
I n c G a l o i s C o u n t e r 5 X 3 2 ( p−>pool . s t a t e )
to initialize the PRNG initial state:
;
sha . s t a t e [ 0] ^= p−>pool . s t a t e [ 4 ] ; • ClockTime [47]: The current system clock time.
sha . s t a t e [ 1] ^= p−>pool . s t a t e [ 3 ] ;
sha . s t a t e [ 2] ^= p−>pool . s t a t e [ 2 ] ; • ClockCycles [46]: The current value of a free-
sha . s t a t e [ 3] ^= p−>pool . s t a t e [ 1 ] ; running 64-bit clock cycle counter.
sha . s t a t e [ 4] ^= p−>pool . s t a t e [ 0 ] ;
• PIDs: The currently active process IDs by walking
SHA1Update(&sha , c t x−>i v , 20) ; the /proc directory.
SHA1Final ( c t x−>out , &sha ) ;
}
• Device Names: The currently available device
names by walking the /dev directory.
While all the above discussed divergences are
at the very least ill-advised, the reseeding control In order to evaluate random’s boottime entropy
issues constitute a clear security issue. In the case quality we used the NIST SP800-90B [41] Entropy
of absent reseeding control, it eliminates Yarrow’s Source Testing (EST) tool [38] to evaluate
intended defense against state compromise as well as boottime entropy by means of a min entropy estimate.
greatly increasing system susceptibility to the so-called We collected random’s boottime entropy from 50
"boottime entropy hole" [10] that affects embedded different reboot sessions on the same device (by
systems. In the case of the QNX Yarrow 6.6 custom instrumenting yarrow_init_poll and logging the
reseeding control no entropy quality estimation is collected raw noise) and using NIST EST determined
Page 15 of 22
Dissecting QNX
that the average min-entropy was 0.02765687, which program image base addresses, register values,
is far less than 1 bit of min-entropy per 8 bits of flag values, task priority, etc.) for every currently
raw noise. In addition to the boottime entropy of active process.
individual boot sessions being of low quality, the
static or minimally variable nature of many of the • High-Performance Clock Timing: This source
boottime noise sources (identical processes and draws entropy from the PRNG (using the
devices available upon reboot, real-time nature of yarrow_output function), initiates a delay (in
QNX limiting jitter between kernel calls thus reducing milliseconds) based on the PRNG output, invokes
ClockCycles entropy, etc.) results in predictable and ClockCycles and xors the result against the
consistent patterns across reboots. earlier obtained PRNG output and feeds this into
the entropy pool.
Another boottime entropy issue with QNX’s random • User-Supplied Input (Undocumented): In QNX
service is the fact that the service is started as a process 6.6 the random service has a write-handler made
by startup.sh. As a result, the CSPRNG is only avail- available to users via the kernel resource manager
able quite late in the boot process and many services (in the form of handling write operations to the
which need it (eg. sshd) start almost immediately after. /dev/(u)random interfaces) which takes arbitrary
Since random only offers non-blocking interfaces, this user inputs of up to 1024 bytes per write opera-
means that one can draw as much output from the tion and feeds it directly into the entropy pool by
CSPRNG as one wants immediately upon availability passing it to the yarrow_input operation. Write
of the device interface. Hence, many applications operations of this kind are restricted to the root
which start at boot and require secure random data user only.
have their ’randomness’ determined almost completely
by the (very low quality) boottime raw noise since After initialization, random starts a thread for each
there is little time for the QNX random service to entroy source which will gather entropy and store it
gather runtime entropy before being queried thus am- in the entropy pool. Contrary to our analysis of QNX
plifying the impact of the "boot-time entropy hole" [10]. random’s boottime entropy, we did not perform a run-
time entropy quality evaluation because during our
Runtime Entropy Analysis: The QNX random ser- contact with the vendor they had already indicated
vice leaves the choice and combination of runtime en- the current design would be overhauled in upcoming
tropy sources (as illustrated in Figure 10) up to the patches and future releases as a result of our findings.
person configuring the system with the following op- In addition, in all QNX versions except for 6.6 runtime
tions: entropy is accumulated but not used due to the pre-
viously mentioned absent reseeding control. We did
• Interrupt Request Timing: Up to 32 different have the following observations however:
interrupt numbers may be specified to be used as
an entropy source. The entropy here is derived • Entropy Source Configuration: Configuring
from interval timing measurements (measured by runtime entropy sources is entirely left to system
the ClockTime kernel call) between requests to a integrators. Since the entropic quality of certain
specific interrupt. sources (eg. interrupt request timings or system
information polling) varies depending on the
• System Information Polling: This source col- particular system, it is non-trivial to pick suitable
lects entropy from system information via the sources.
procfs [48] virtual filesystem in /proc. This
information is composed of process and thread • System Information Entropy Source: System
information (process and thread IDs, stack and information polling gathers raw noise from
Page 16 of 22
Dissecting QNX
ClockCycles()
delay ClockCycles SH A1 delay wakeup_timer
PR N G Input Block
pid_unique
ClockTime kernel_exit_count
yarrow_output yarrow_input
qtimeptr->nsec
interrupt invoked
ClockTime U ndocumented
>= N times? entropy_source_start dev_random_write
Sources
O utput:
5.2 QNX 7.0 Kernel PRNG R andom Value
(32-bit)
QNX 7 has a new kernel PRNG for generation of secure Figure 11: QNX Kernel PRNG
random numbers implemented in the microkernel’s
random_value function. As shown in Listing 17 and Kernel PRNG entropy is drawn from a combination
illustrated in Figure 11, the kernel PRNG consists of a of the following values:
256-bit seed block fed through SHA256 to produce a
digest from which 32-bit random numbers are drawn
iteratively before reseeding after exhausting the entire • salt: A salt value which starts out as 0 and then
digest. gets filled with the first non-zero 32 bits of every
newly generated digest.
Listing 17: QNX 7 Kernel PRNG • ClockCycles: The current clock cycle counter
unsigned i n t random_value ( ) value.
{
Page 17 of 22
Dissecting QNX
onds.
Clock Source
SH A256 delay
fortuna_pseudorand
• wakeup_timer: The timer wakeup value [45]. fortuna_pseudorand fortuna_add add_entropy PR N G state
Source
gettimeofday()
Finally, note that all sources are truncated to • User-Supplied Input: Anything written to the
32-bit values when stored in the seed block, that /dev/(u)random device is immediately absorbed
random_seed is only initialized when system integra- into the PRNG state and, if seedfile state persis-
tors utilize it and that the final block (keypad[7]) is tence is enabled, the state is saved as well. It
never initialized. As such, in many cases the theoretical is possible to shield this functionality with the
maximum of the entropy contained within the seed -m mode option specifying permissions but by
block would be reduced to 192 bits. A full evaluation default the interface is world-writable which
of the entropic quality of the QNX 7 kernel PRNG is could possibly present an avenue for reseeding
left to future work. attacks.
Page 18 of 22
Dissecting QNX
uid_t u = getuid () ;
add_entropy (& m a i n _ s t a t e , ( void * )&u ,
gations as they have evolved in the general purpose
sizeof (u) ) ; world, the fact that it is a proprietary OS outside
of the Linux, Windows and BSD lineages means
return entropy_p ; that they cannot trivially port mitigations, patches
} and improvements from these operating systems.
In addition, the relative lack of attention to QNX
Due to the elimination of dedicated boottime en- by outside security researchers is evident from the
tropy harvesting and its rapid startup time, QNX 7 degree to which certain vulnerabilities and issues
Fortuna is likely to suffer from the "boottime entropy (such as the local information leaks or the "poor man’s
hole" (unless system integrators explicitly enable seed- randomization patch" design for ASLR/SSP) resemble
files / state persistence) but we leave a full analysis of older vulnerabilities on other Unix-like systems.
entropic quality to future work. Finally, our findings re-confirm the notion that secure
random number generation and especially integrating
suitable entropy sources is an issue that continues to
6 Conclusion plague the embedded world. The impact of this goes
beyond affecting the quality of exploit mitigations and
We reverse-engineered and analyze the exploit has consequences for the wider security ecosystem as
mitigations and secure random number generators a whole.
of QNX ≤ 6.6 and 7.0 and found and reported a
myriad of issues of varying degrees of severity. Table It is our hope that this work inspires other security
11 presents an overview of the analyzed mitigations researchers to further investigate the security and OS
and RNGs, their issues and what versions are affected internals of QNX and other closed-source embedded
by them. Note that we have left proper RNG entropy operating systems.
quality and ASLR correlation attack evaluation of QNX
7’s to future work and as such we can neither confirm
nor rule out issues in this regard. Bibliography
We can see that despite our disclosure of the issues [1] Alex Plaskett et al. QNX: 99 Problems but a Mi-
affecting QNX 6.6 and subsequent fixes being drafted crokernel ain’t one! 2016.
for the bulk of them, some of them remained in QNX
[2] Daniel J. Bernstein et al. “Factoring RSA keys
7.0. Regardless, General Availability (GA) patches
from certified smart cards: Coppersmith in the
are available for all issues affecting QNX ≤ 6.6 in
wild”. In: ASIACRYPT (2013).
Table 11 (naturally excluding those affecting QNX 7.0).
[3] Daniel Martin Gomez et al. BlackBerry PlayBook
One striking observation is that while QNX clearly Security: Part one. 2011.
attempts to keep up with at least basic exploit miti-
Page 19 of 22
Dissecting QNX
[4] David Kaplan et al. “Attacking the Linux PRNG [20] c0ntex. How to hijack the Global Offset Table
on Android & Embedded Devices”. In: Black Hat with pointers for root shells. url: http://www.
Europe (2014). url: https://www.blackhat. infosecwriters.com/text_resources/pdf/
com/docs/eu- 14/materials/eu- 14- Kedmi- GOT_Hijack.pdf.
Attacking - The - Linux - PRNG - On - Android - [21] Communications Security Establishment
Weaknesses - In - Seeding - Of - Entropic - Canada. EAL 4+ Evaluation of QNX Neutrino®
Pools-And-Low-Boot-Time-Entropy.pdf. Secure Kernel v6.4.0. 2009. url: https :
[5] Hector Marco-Gisbert et al. “Preventing brute / / www . commoncriteriaportal . org / files /
force attacks against stack canary protection epfiles/neutrino-v640-cert-eng.pdf.
on networking servers”. In: 12th IEEE Interna- [22] Silvio Cesare. CVE-2004-1453. 2004. url: http:
tional Symposium on Network Computing and / / www . cve . mitre . org / cgi - bin / cvename .
Applications (NCA) (2013). cgi?name=CVE-2004-1453.
[6] Hector Marco-Gisbert et al. “On the Effective- [23] Colt. Android OS - Processes and the Zygote! url:
ness of Full-ASLR on 64-bit Linux”. In: DeepSec http://coltf.blogspot.nl/p/android-os-
(2014). processes-and-zygote.html.
[7] Hector Marco-Gisbert et al. “Exploiting Linux [24] Counterpane. Yarrow 0.8.71. url: https : / /
and PaX ASLR’s weaknesses on 32- and 64-bit www.schneier.com/code/Yarrow0.8.71.zip.
systems”. In: BlackHat Asia (2016).
[25] CVE Details. QNX CVEs. url: https : / / www .
[8] John Kelsey et al. “Yarrow-160: Notes on the De- cvedetails . com / vulnerability - list /
sign and Analysis of the Yarrow Cryptographic vendor_id-436/QNX.html.
Pseudorandom Number Generator”. In: Sixth
[26] Jake Edge. proc: avoid information leaks to
Annual Workshop on Selected Areas in Cryptog-
non-privileged processes. 2009. url: https://
raphy (1999).
patchwork.kernel.org/patch/21766/.
[9] Keaton Mowery et al. “Welcome to the Entropics:
[27] Julio Cesar Fort. QNX Advisories. url: https://
Boot-Time Entropy in Embedded Devices”. In:
packetstormsecurity . com / files / author /
IEEE Security and Privacy (2013).
3551/.
[10] Nadia Heninger et al. “Mining Your Ps and
[28] Hagen Fritsch. Buffer overflows on linux-x86-64.
Qs: Detection of Widespread Weak Keys in Net-
2009.
work Devices”. In: USENIX Security Symposium
(2012). [29] Hagen Fritsch. Stack Smashing as of Today.
2009.
[11] Niels Ferguson et al. Practical Cryptography. Wi-
ley, 2003. [30] Manu Garg. About ELF Auxiliary Vectors. url:
http : / / articles . manugarg . com /
[12] Tavis Ormandy et al. Linux ASLR Curiosities.
aboutelfauxiliaryvectors.
2009. url: https://www.cr0.org/paper/to-
jt-linux-alsr-leak.pdf. [31] Hector Marco Gisbert. “Cyber-security protec-
tion techniques to mitigate memory errors
[13] Zach Lanier et al. Voight-Kampff’ing The Black-
exploitation”. In: (2015). url: https : / /
Berry PlayBook. 2012.
riunet . upv . es / bitstream / handle /
[14] Zach Lanier et al. No Apology Required: Decon- 10251 / 57806 / Marco % 20 - %20Cyber -
structing BB10. 2014. security % 20protection % 20techniques %
[15] Alexander Antukh. Dissecting Blackberry 10 – 20to % 20mitigate % 20memory % 20errors %
An initial analysis. 2013. 20exploitation . pdf ? sequence = 1 &
[16] BlackBerry. Using compiler and linker defenses isAllowed=y.
(BlackBerry Native SDK for PlayBook OS). url: [32] Heimdal. The Heimdal Kerberos 5, PKIX, CMS,
http : / / developer . blackberry . com / GSS-API, SPNEGO, NTLM, Digest-MD5 and, SASL
playbook / native / reference / com . qnx . implementation. url: http://www.h5l.org/.
doc . native _ sdk . security / topic / using _ [33] Alejandro Hernandez. A Short Tale About exe-
compiler_linker_defenses.html. cutable_stack in elf_read_implies_exec() in the
[17] BlackBerry. QNX. 2017. url: http://www.qnx. Linux Kernel. url: http : / / blog . ioactive .
com/content/qnx/en.html. com / 2013 / 11 / a - short - tale - about -
[18] Robert G. Brown. Dieharder: A Random Number executablestack-in.html.
Test Suite. url: https://www.phy.duke.edu/ [34] Tobias Klein. checksec. url: http : / / www .
\~rgb/General/dieharder.php. trapkit.de/tools/checksec.html.
[19] Tim Brown. QNX Advisories. url: https : / / [35] Gentoo Linux. Hardened/GNU stack quickstart.
packetstormsecurity . com / files / author / url: https : / / wiki . gentoo . org / wiki /
4309/. Hardened/GNU_stack_quickstart.
Page 20 of 22
Dissecting QNX
[36] Matt Miller. “Reducing the Effective Entropy of [51] QNX Software Systems. On. url: http : / /
GS Cookies”. In: Uninformed Vol. 7 (2007). www.qnx.com/developers/docs/660/index.
[37] Bojan Nikolic. The LD_DEBUG environment vari- jsp ? topic = %2Fcom . qnx . doc . neutrino .
able. url: http : / / www . bnikolic . co . uk / utilities%2Ftopic%2Fo%2Fon.html.
blog/linux-ld-debug.html. [52] QNX Software Systems. pidin. url: http : / /
[38] NIST. NIST Entropy Source Testing (EST) tool. www . qnx . com / developers / docs / 660 /
url: https : / / github . com / usnistgov / index.jsp?topic=/com.qnx.doc.neutrino.
SP800-90B_EntropyAssessment. utilities/topic/p/pidin.html.
[39] NIST. NIST Statistical Test Suite (STS). url: [53] QNX Software Systems. Private virtual memory.
http : / / csrc . nist . gov / groups / ST / url: http : / / www . qnx . com / developers /
toolkit / rng / documentation \ _software . docs / 660 / index . jsp ? topic = %2Fcom . qnx .
html. doc.neutrino.sys_arch%2Ftopic%2Fproc_
Private_virtual_memory.html.
[40] NIST. “NIST SP800-22: A Statistical Test Suite
for Random and Pseudorandom Number Gener- [54] QNX Software Systems. Procmgr abilities. url:
ators for Cryptographic Applications”. In: NIST http://www.qnx.com/developers/docs/6.
(2010). 6.0.update/#com.qnx.doc.neutrino.prog/
topic/process_Procmgr_abilities.html.
[41] NIST. “NIST SP800-90B: Recommendation for
the Entropy Sources Used for Random Bit Gen- [55] QNX Software Systems. Procnto. url: http://
eration”. In: NIST (2016). www.qnx.com/developers/docs/660/index.
jsp ? topic = %2Fcom . qnx . doc . neutrino .
[42] Alex Plaskett. QNX Security Architecture. 2016. utilities/topic/p/procnto.html.
[43] Paul Rascagneres. Stack Smashing Protector. [56] QNX Software Systems. Random. url: http://
2010. www.qnx.com/developers/docs/660/index.
[44] Fermin J. Serna. “The info leak era on software jsp ? topic = %2Fcom . qnx . doc . neutrino .
exploitation”. In: Black Hat US (2012). utilities/topic/r/random.html.
[45] QNX Software Systems. Clock and timer services. [57] QNX Software Systems. Shared memory. url:
url: http : / / www . qnx . com / developers / http://www.qnx.com/developers/docs/7.0.
docs / 7 . 0 . 0 / index . html # com . qnx . 0/index.html#com.qnx.doc.neutrino.sys_
doc . neutrino . sys _ arch / topic / kernel _ arch/topic/ipc_Shared_memory.html.
CLOCKANDTIMER.html. [58] QNX Software Systems. SysSrandom(), SysSran-
[46] QNX Software Systems. ClockCycles(). url: dom_r(). url: http : / / www . qnx . com /
http : / / www . qnx . com / developers / docs / developers / docs / 7 . 0 . 0 / index . html #
660 / index . jsp ? topic = %2Fcom . qnx . com . qnx . doc . neutrino . lib _ ref / topic /
doc . neutrino . lib _ ref % 2Ftopic % 2Fc % s/syssrandom.html.
2Fclockcycles.html. [59] QNX Software Systems. Typed memory. url:
[47] QNX Software Systems. ClockTime(), Clock- http : / / www . qnx . com / developers / docs /
Time_r(). url: http : / / www . qnx . com / 7.0.0/index.html#com.qnx.doc.neutrino.
developers/docs/660/topic/com.qnx.doc. sys_arch/topic/ipc_Typed_memory.html.
neutrino . lib _ ref / topic / c / clocktime . [60] QNX Software Systems. QNX Neutrino RTOS:
html. System Architecture. 2014. url: http : / /
[48] QNX Software Systems. Controlling processes via support7 . qnx . com / download / download /
the /proc filesystem. url: http : / / www . qnx . 26183 / QNX _ Neutrino _ RTOS _ System _
com / developers / docs / 660 / index . jsp ? Architecture.pdf.
topic = %2Fcom . qnx . doc . neutrino . prog % [61] QNX Software Systems. 50 Million Vehicles and
2Ftopic%2Fprocess_proc_filesystem.html. Counting: QNX Achieves New Milestone in Auto-
[49] QNX Software Systems. DCMD_PROC_INFO. motive Market. 2015. url: http://www.qnx.
url: http : / / www . qnx . com / developers / com/news/pr_6118_3.html.
docs / 660 / index . jsp ? topic = %2Fcom . qnx . [62] Julien Tinnes. Local bypass of Linux ASLR
doc . neutrino . cookbook % 2Ftopic % 2Fs3 _ through /proc information leaks. 2009. url:
procfs_DCMD_PROC_INFO.html. http : / / blog . cr0 . org / 2009 / 04 / local -
[50] QNX Software Systems. devctl. url: http:// bypass - of - linux - aslr - through - proc .
www.qnx.com/developers/docs/660/index. html.
jsp?topic=%2Fcom.qnx.doc.neutrino.lib_ [63] Ubuntu. ld.so, ld-linux.so - dynamic linker/loader.
ref%2Ftopic%2Fd%2Fdevctl.html. 2017. url: http://manpages.ubuntu.com/
manpages/xenial/man8/ld.so.8.html.
Page 21 of 22
Dissecting QNX
Page 22 of 22