feat(ld-preload): add standalone libtermux-paths-ld-preload.so for /etc/ file access redirection#36
feat(ld-preload): add standalone libtermux-paths-ld-preload.so for /etc/ file access redirection#36rios0rios0 wants to merge 3 commits intotermux:masterfrom
libtermux-paths-ld-preload.so for /etc/ file access redirection#36Conversation
- added `FileAccessIntercept` module that redirects reads of standard Linux `/etc/` configuration files to their Termux `$PREFIX/etc/` equivalents - added interceptors for `open`, `openat`, `fopen`, `access`, `faccessat`, `stat`, and `lstat` to the direct LD_PRELOAD entry point - redirected `/etc/resolv.conf`, `/etc/hosts`, `/etc/nsswitch.conf` for DNS resolution - redirected Go's hardcoded SSL CA certificate paths (`/etc/ssl/certs/ca-certificates.crt`, `/etc/pki/tls/certs/ca-bundle.crt`, etc.) to `$PREFIX/etc/tls/cert.pem` This fixes DNS resolution and TLS certificate verification for dynamically linked programs on Termux, where Android does not provide these files at their standard Linux paths. Closes termux/termux-packages#10277 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR extends the libtermux-exec-direct-ld-preload.so LD_PRELOAD layer to redirect access to select standard Linux /etc/* DNS and CA-bundle paths to their Termux $PREFIX/etc/* equivalents, improving DNS resolution and TLS verification for dynamically linked programs on Android/Termux.
Changes:
- Added a
FileAccessInterceptmodule with a fixed redirect table and existence-checking logic. - Hooked libc file-access APIs (
open,openat,fopen,access,faccessat,stat,lstat) in the direct LD_PRELOAD entry point to apply redirection. - Updated build inputs to compile the new interception module into the library.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| Makefile | Adds the new FileAccessIntercept.c source to the static library build inputs. |
| lib/termux-exec_nos_c/tre/src/.../FileAccessIntercept.c | Implements redirect-table lookup + $PREFIX path construction + existence check via raw syscall. |
| lib/termux-exec_nos_c/tre/include/.../FileAccessIntercept.h | Declares redirect structures and fileAccess_redirectPath() API for consumers. |
| app/.../TermuxExecDirectLDPreloadEntryPoint.c | Introduces LD_PRELOAD interceptors for file-access libc functions and applies redirection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...d/src/termux/api/termux_exec/service/ld_preload/direct/TermuxExecDirectLDPreloadEntryPoint.c
Outdated
Show resolved
Hide resolved
...d/src/termux/api/termux_exec/service/ld_preload/direct/TermuxExecDirectLDPreloadEntryPoint.c
Outdated
Show resolved
Hide resolved
...d/src/termux/api/termux_exec/service/ld_preload/direct/TermuxExecDirectLDPreloadEntryPoint.c
Outdated
Show resolved
Hide resolved
..._exec__nos__c/v1/termux/api/termux_exec/service/ld_preload/direct/file/FileAccessIntercept.h
Show resolved
Hide resolved
...ec_nos_c/tre/src/termux/api/termux_exec/service/ld_preload/direct/file/FileAccessIntercept.c
Show resolved
Hide resolved
| /* | ||
| * File access interceptors for `/etc/` path redirection. | ||
| * | ||
| * These intercept libc file-access functions and redirect reads of | ||
| * standard Linux `/etc/` configuration files (resolv.conf, hosts, | ||
| * nsswitch.conf, SSL CA certificates) to their Termux equivalents | ||
| * under `$PREFIX/etc/`. | ||
| * | ||
| * This fixes DNS resolution and TLS certificate verification for | ||
| * dynamically linked programs on Termux, where Android does not | ||
| * provide these files at their standard paths. | ||
| */ |
There was a problem hiding this comment.
There are runtime-binary tests for the existing exec interceptors, but no automated tests were added for the new /etc/* redirection behavior (open/openat/fopen/access/stat/lstat). Adding a small runtime test that validates redirected reads for one DNS file and one CA-bundle path (and validates a non-redirected control like /etc/passwd) would help prevent regressions.
There was a problem hiding this comment.
Valid feedback. The existing test infrastructure
(ExecIntercept_RuntimeBinaryTests.c) uses a complex
fork + LD_PRELOAD setup focused on exec
interception. Adding file access tests would require a
similar but separate test harness. Suggest addressing
this in a follow-up PR to keep this one focused.
Happy to discuss if a specific test approach is
preferred.
- resolved dlsym symbols at load time via __attribute__((constructor)) for thread safety - added NULL checks with ENOSYS errno for all file intercept functions - updated comments to clarify all access modes are redirected, not just reads - added missing /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem to header docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Hi thanks for the PR.
Thank you for your submission, please be aware that it may take some time before a maintainer has time to review your PR.
|
Hi Tom, thanks for the quick feedback!
I appreciate the team's time. |
sylirre
left a comment
There was a problem hiding this comment.
termux-exec package intended only to hook exec* functions. This is why it has such name.
Your pull request adds unrelated functionality that implicitly redirects file access path and does not have any way to opt out.
IMO /etc/file fix should go as separate LD_PRELOAD lib.
|
IMO this would be a good change for an experimental 3rd party Termux fork, like a fork where experimental changes that might have unexpected tradeoffs can be tested with various packages and people can report back which things were broken by them. Here is an example of a precedent of a different project doing that: Flips https://github.com/Alcaro/Flips has split into 2 new projects, This one, which is a non-AI project, https://git.disroot.org/Sir_Walrus/Flips and this one, which is an AI-only project, https://github.com/Alcaro/FlAIps both forks are maintained by the original creator and they are an experiment to find out what would happen if a project had an AI version and a non-AI version, I don't think that Termux needs to have as strict of a setup as that, but basically my idea is that this PR, and maybe other similar changes together with it, should go in another build of Termux, if their creators are motivated to make one, and then people can test that build and give feedback on the special features, and then from there if there are certain good features people like they can be added to another PR directly to the regular Termux repositories, and get added like that. |
Where is that one? Could you point the right direction so I can go there and fix? Because the current issue is really annoying. I can't run natively GitHub CLI, Kubernetes, Terraform and any other binary that refers to /etc. |
Could you show which version of GitHub CLI you are trying to use? Is it one from |
Yes, official package. But look, any other GOOS=Linux that is built outside Android, does not work as well. They expect Linux paths, and the PREFIX Termux adds are not respected. |
|
Could you show which |
The command to run without proot: GH_DEBUG=1 ~/.local/bin/gh_linux_arm64 auth status The error is: dial tcp: lookup api.github.com on [::1]:53: read udp [::1]:51780->[::1]:53: read: connection refused Go's net package can't resolve DNS because it looks for /etc/resolv.conf (doesn't exist natively on Android) and falls back to [::1]:53 which also doesn't work. |
…one `libtermux-paths-ld-preload.so` - moved `/etc/` path redirection interceptors (`open`, `openat`, `fopen`, `access`, `faccessat`, `stat`, `lstat`) from `TermuxExecDirectLDPreloadEntryPoint.c` into a new standalone entry point `TermuxPathsLDPreloadEntryPoint.c` - reverted `TermuxExecDirectLDPreloadEntryPoint.c` to exec-only interception - added `build-libtermux-paths-ld-preload` Makefile target with install, uninstall, format, and check support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
/etc/file access interception for DNS and TLSlibtermux-paths-ld-preload.so for /etc/ file access redirection
this is not |
You are right about that. I was installing the raw binary built with GOOS=Linux instead of PKG version. Anyways, thanks. But it doesn't solve the PR point, because not all binaries have Termux versions for them and it is also very costly to keep alternative versions of all packages always whenever a useful stuff lunches or when gets updated. The easiest would be making Termux compatible with those Linux binaries. |
|
Actually you are right, and I do think the idea is interesting and could be useful, I am just concerned that it might have unexpected effects on some programs that previously didn't have a Something I was wondering is, do you know of any specific precompiled Linux executables that need this that I could use to test the behavior of this PR easily? Something that starts to work in Termux, but does not work properly without this PR because of the problem with the hardcoded I recently added a package |
|
Also like others said, probably this change should be tested as an individual package if it's possible to do that. Do you think it's possible for this to be refactored to be built in a standalone project separate from |
|
And is it possible for this to operate in a way that has no relationship with |
You can use with the official GH CLI, just download the raw binary and you'll see. |
By the analysis I did, yes. I did not see other way of doing it. If you find, please point me the right direction and I'll do, I would perform the tests and show the evidences if you guys wish. |




Summary
FileAccessInterceptmodule that redirects accesses of standard Linux/etc/configuration files to their Termux$PREFIX/etc/equivalentsopen,openat,fopen,access,faccessat,stat, andlstatin a separate, opt-inLD_PRELOADlibrary (libtermux-paths-ld-preload.so)/etc/resolv.conf,/etc/hosts,/etc/nsswitch.conffor DNS resolution$PREFIX/etc/tls/cert.pemlibtermux-exec-direct-ld-preload.soremains exec-only — file access interception is fully decoupledProblem
On Android/Termux, standard Linux paths like
/etc/resolv.conf,/etc/hosts, and/etc/ssl/certs/either don't exist or contain incomplete data. Termux maintains proper versions under$PREFIX/etc/, but many dynamically linked programs hardcode the standard/etc/paths.This causes DNS resolution failures and TLS certificate verification errors for tools like Python, Node.js, and cgo-enabled Go programs running in Termux.
Solution
Introduce a new standalone
libtermux-paths-ld-preload.solibrary that intercepts file-access libc functions (open,openat,fopen,access,faccessat,stat,lstat) and redirects a fixed set of/etc/paths to their$PREFIX/etc/equivalents.This library is separate from
termux-execand fully opt-in. Users enable it by adding it toLD_PRELOAD:Or standalone (without exec interception):
The redirect only applies when:
faccessatsyscall to avoid recursion)Architecture
The redirect logic (
fileAccess_redirectPath()) lives in the shared librarylibtermux-exec_nos_c_treand is reusable. The new entry point (TermuxPathsLDPreloadEntryPoint.c) provides theLD_PRELOADhooks that call this logic. The existingTermuxExecDirectLDPreloadEntryPoint.cremains unchanged from upstream — exec-only.Redirected paths
/etc/resolv.conf$PREFIX/etc/resolv.conf/etc/hosts$PREFIX/etc/hosts/etc/nsswitch.conf$PREFIX/etc/nsswitch.conf/etc/ssl/certs/ca-certificates.crt$PREFIX/etc/tls/cert.pem/etc/pki/tls/certs/ca-bundle.crt$PREFIX/etc/tls/cert.pem/etc/ssl/ca-bundle.pem$PREFIX/etc/tls/cert.pem/etc/pki/tls/cacert.pem$PREFIX/etc/tls/cert.pem/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem$PREFIX/etc/tls/cert.pem/etc/ssl/cert.pem$PREFIX/etc/tls/cert.pemLimitations
This only fixes dynamically linked programs. Statically linked Go binaries (e.g.,
terraform,gh,kubectl) use raw syscalls and bypass libc entirely — they require a different solution (seccompuser_notifor proot).Test plan
fopen("/etc/resolv.conf")returns Termux contentfopen("/etc/hosts")returns Termux contentopen("/etc/ssl/certs/ca-certificates.crt")returns Termux cert bundle/etc/paths (e.g.,/etc/passwd) are NOT redirectedexecve()interception testslibtermux-exec-direct-ld-preload.soexports only exec symbolslibtermux-paths-ld-preload.soexports only file access symbolsCloses termux/termux-packages#10277