Add getauxval availability detection with /proc/self/auxv fallback for uclibc targets#3250
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3250 +/- ##
==========================================
- Coverage 78.28% 78.12% -0.17%
==========================================
Files 689 689
Lines 123463 123460 -3
Branches 17200 17195 -5
==========================================
- Hits 96659 96447 -212
- Misses 25881 26093 +212
+ Partials 923 920 -3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
getauxval availability detection with /proc/self/auxv fallback for uclibc targetsgetauxval availability detection with /proc/self/auxv fallback for uclibc targets
nebeid
left a comment
There was a problem hiding this comment.
Is OPENSSL_GETAUXVAL_FORCE_PROC_FALLBACK exercised anywhere in CI? I see it documented but not used in the new workflow. If it's purely for local developer testing that's fine, but it could also be a cheap way to regression-test the fallback on glibc runners without needing a separate toolchain.
On Linux targets using older uclibc/uclibc-ng, <sys/auxv.h> and
getauxval are not available, causing hard build failures in the ARM,
AArch64, and PPC64LE CPU capability detection code, as well as in the
urandom entropy path.
Introduce a shared header (cpu_getauxval_linux.h) that uses
__has_include(<sys/auxv.h>) to detect availability at the preprocessor
level, falling back to library-specific heuristics (__GLIBC_PREREQ,
!__UCLIBC__) on compilers without __has_include. When the header is
absent, a fallback reads /proc/self/auxv directly and defines the
AT_HWCAP, AT_HWCAP2, and AT_EXECFN constants from the Linux kernel ABI.
The fallback retries open()/read() on EINTR and loops over short reads,
and is marked OPENSSL_UNUSED so translation units that include the
header without calling getauxval do not trip -Wunused-function.
After including the header, OPENSSL_HAS_GETAUXVAL is defined whether
the real libc entry point or the /proc/self/auxv fallback is in use,
so call sites can gate uniformly on "getauxval is callable" without
caring which path was taken.
Apply the shared helper to:
- crypto/fipsmodule/cpucap/cpu_arm_linux.c
- crypto/fipsmodule/cpucap/cpu_aarch64_linux.c
- crypto/fipsmodule/cpucap/cpu_ppc64le.c (Linux path only; FreeBSD
continues to use its own <sys/auxv.h>/elf_aux_info path)
- crypto/rand_extra/urandom.c (replaces the previous __GLIBC_PREREQ-
only detection; Android continues to skip the AT_EXECFN debug
lookup to avoid depending on getauxval in older NDK sysroots)
Also note the /proc/self/auxv fallback in SANDBOXING.md so sandbox
authors on uclibc targets know to allow it. The note now covers all
auxv-using paths (ARM, AArch64, PPC64LE, and urandom's debug lookup).
Add a new CI job, armv7-uclibc-build-test, that builds and tests
against Bootlin's armv7-eabihf--uclibc--stable-2022.08-1 toolchain
(uclibc-ng 1.0.42). This release predates uclibc-ng's own <sys/auxv.h>
(added in 1.0.43), so __has_include() in the shared header evaluates
false and the natural detection path lands on the /proc/self/auxv
fallback -- i.e. a single job exercises both the non-glibc detection
logic and the fallback code end-to-end under QEMU user-mode. The
OPENSSL_GETAUXVAL_FORCE_PROC_FALLBACK knob is kept in the header as a
developer debugging aid even though CI no longer needs it.
A new helper, tests/ci/run_cross_tests_bootlin.sh, handles Bootlin's
directory layout (which differs from the aws-libcrypto S3 mirror
consumed by run_cross_tests.sh) and pins the tarball by SHA-256.
This allows uclibc-based targets (e.g. armv7-unknown-linux-uclibceabihf)
to build out of the box while preserving runtime CPU feature detection.
Resolves aws#3188
…ck CI - Add defined(AT_HWCAP2) guard on the FreeBSD path in cpu_ppc64le.c, consistent with cpu_arm_freebsd.c. - Exercise OPENSSL_GETAUXVAL_FORCE_PROC_FALLBACK in the ppc64le CI job to regression-test the /proc/self/auxv fallback on a 64-bit glibc target.
Added it as a third build pass on the |
### Description of changes: The `/proc/self/auxv` fallback added in #3250 unconditionally references `O_CLOEXEC`, which breaks the build on manylinux1 (CentOS 5, glibc 2.5). `O_CLOEXEC` was introduced in Linux 2.6.23 / glibc 2.7 (Oct 2007), so it's absent from manylinux1's `<fcntl.h>`. Defining `O_CLOEXEC` to `0` when not provided is sufficient. In this fallback path the fd is opened, read, and closed synchronously inside `getauxval()` with no intervening `fork()`, so the close-on-exec semantics aren't security-relevant here — it's purely a syntactic dependency. ### Call-outs: manylinux1 is exactly the environment that should land on this fallback path: it doesn't ship `<sys/auxv.h>`, so `__has_include` correctly steers it into the `/proc/self/auxv` reader. The bug is just that the reader itself wasn't quite portable enough. ### Testing: Existing CI exercises both code paths via `OPENSSL_GETAUXVAL_FORCE_PROC_FALLBACK`. Locally verified that the fallback compiles cleanly with `O_CLOEXEC` undefined (simulating the manylinux1 condition). By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.
Issues:
Addresses:
cpu_arm_linux.candcpu_aarch64_linux.cunconditionally requiregetauxval/<sys/auxv.h>#3188Description of changes:
On Linux targets using older uclibc/uclibc-ng (pre-1.0.43),
<sys/auxv.h>andgetauxvalare not available, causing hard build failures in the ARM, AArch64, and PPC64LE CPU capability detection code and in the urandom entropy path.This introduces a shared header (
cpu_getauxval_linux.h) that detectsgetauxvalavailability at the preprocessor level using__has_include, with library-specific heuristics as a fallback for compilers that lack it. When the header is absent, a fallback reads/proc/self/auxvdirectly. After including the header,OPENSSL_HAS_GETAUXVALis unconditionally defined so call sites don't need to care which path was taken.The shared helper replaces the previous
<sys/auxv.h>includes incpu_arm_linux.c,cpu_aarch64_linux.c, andcpu_ppc64le.c, and supersedes the old glibc-only detection inurandom.c.Call-outs:
The fallback
getauxvalis astaticfunction defined in a header. This means each translation unit that includes it (when the fallback is active) gets its own copy. This is intentional — it avoids needing to wire a new.cfile into the build, and the fallback path only compiles on uclibc targets where<sys/auxv.h>is genuinely missing.The
#if defined(AT_HWCAP2)guard incpu_ppc64le.cis removed because the header now unconditionally definesAT_HWCAP2in the fallback path, and it was always defined via<sys/auxv.h>in the non-fallback path.Testing:
New CI job (
armv7-uclibc-build-test) builds and runs tests against Bootlin's armv7-eabihf uclibc-ng 1.0.42 toolchain under QEMU. This toolchain predates uclibc-ng's<sys/auxv.h>(added in 1.0.43), so__has_includeevaluates false and the/proc/self/auxvfallback is exercised end-to-end without any artificial force-flags.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.