Skip to content

Add getauxval availability detection with /proc/self/auxv fallback for uclibc targets#3250

Merged
justsmth merged 2 commits into
aws:mainfrom
justsmth:sys-auxv-h
May 22, 2026
Merged

Add getauxval availability detection with /proc/self/auxv fallback for uclibc targets#3250
justsmth merged 2 commits into
aws:mainfrom
justsmth:sys-auxv-h

Conversation

@justsmth

@justsmth justsmth commented May 13, 2026

Copy link
Copy Markdown
Contributor

Issues:

Addresses:

Description of changes:

On Linux targets using older uclibc/uclibc-ng (pre-1.0.43), <sys/auxv.h> and getauxval are 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 detects getauxval availability 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/auxv directly. After including the header, OPENSSL_HAS_GETAUXVAL is unconditionally defined so call sites don't need to care which path was taken.

The shared helper replaces the previous <sys/auxv.h> includes in cpu_arm_linux.c, cpu_aarch64_linux.c, and cpu_ppc64le.c, and supersedes the old glibc-only detection in urandom.c.

Call-outs:

The fallback getauxval is a static function 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 .c file 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 in cpu_ppc64le.c is removed because the header now unconditionally defines AT_HWCAP2 in 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_include evaluates false and the /proc/self/auxv fallback 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.

@codecov-commenter

codecov-commenter commented May 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.12%. Comparing base (cf95ba0) to head (4e1b035).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@justsmth justsmth changed the title [DRAFT] Add getauxval availability detection with /proc/self/auxv fallback for uclibc targets Add getauxval availability detection with /proc/self/auxv fallback for uclibc targets May 19, 2026
@justsmth justsmth marked this pull request as ready for review May 19, 2026 17:13
@justsmth justsmth requested a review from a team as a code owner May 19, 2026 17:13
@justsmth justsmth requested review from geedo0 and nebeid May 19, 2026 17:13
geedo0
geedo0 previously approved these changes May 20, 2026
Comment thread crypto/fipsmodule/cpucap/cpu_getauxval_linux.h
Comment thread .github/workflows/cross-test.yml

@nebeid nebeid left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread crypto/fipsmodule/cpucap/cpu_ppc64le.c
justsmth added 2 commits May 22, 2026 13:21
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.
@justsmth

Copy link
Copy Markdown
Contributor Author

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.

Added it as a third build pass on the ppc64le-build-test job. Gives us 64-bit fallback coverage on glibc alongside the natural 32-bit coverage from the uclibc armv7 job.

@justsmth justsmth requested review from geedo0 and nebeid May 22, 2026 17:43
@justsmth justsmth enabled auto-merge (squash) May 22, 2026 18:14
@justsmth justsmth merged commit b31b37d into aws:main May 22, 2026
487 of 490 checks passed
justsmth added a commit that referenced this pull request May 23, 2026
### 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants