diff --git a/LICENSE b/LICENSE index 89a65e4..8fafe9d 100644 --- a/LICENSE +++ b/LICENSE @@ -7,4 +7,8 @@ Files: Comment: The `termux-exec` repository is released under the `Apache-2.0` license, unless specified differently in a file/directory or in any additional `Files` sections below. -License: [Apache-2.0](licenses/termux__termux-exec-package__Apache-2.0.md) +License: [Apache-2.0](licenses/termux__termux-exec-package__Aache-2.0.md) + +Files: + site/* +License: [MIT](licenses/termux__termux-exec-package__MIT.md) diff --git a/README.md b/README.md index aae5c9d..7d03e5a 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,23 @@ -# termux-exec -A `execve()` wrapper to fix two problems with exec-ing files in Termux. +# termux-exec-package -# Problem 1: Cannot execute files not part of the APK -Android 10 started blocking executing files under the app data directory, as -that is a [W^X](https://en.wikipedia.org/wiki/W%5EX) violation - files should be either -writeable or executable, but not both. Resources: +The [`termux-exec`](https://github.com/termux/termux-exec) package provides a shared library that is meant to be preloaded with [`LD_PRELOAD`](https://man7.org/linux/man-pages/man8/ld.so.8.html) for proper functioning of the Termux execution environment. -- [Google Android issue](https://issuetracker.google.com/issues/128554619) -- [Termux: No more exec from data folder on targetAPI >= Android Q](https://github.com/termux/termux-app/issues/1072) -- [Termux: Revisit the Android W^X problem](https://github.com/termux/termux-app/issues/2155) +### Contents -While there is merit in that general principle, this prevents using Termux and Android -as a general computing device, where it should be possible for users to create executable -scripts and binaries. +- [Project](#project) -# Solution 1: Cannot execute files not part of the APK -Create an `exec` interceptor using [LD_PRELOAD](https://en.wikipedia.org/wiki/DLL_injection#Approaches_on_Unix-like_systems), -that instead of executing an ELF file directly, executes `/system/bin/linker64 /path/to/elf`. -Explanation follows below. +--- -On Linux, the kernel is normally responsible for loading both the executable and the -[dynamic linker](https://en.wikipedia.org/wiki/Dynamic_linker). The executable is invoked -by file path with the [execve system call](https://en.wikipedia.org/wiki/Exec_(system_call)). -The kernel loads the executable into the process, and looks for a `PT_INTERP` entry in -its [ELF program header table](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#Program_header) -of the file - this specifies the path to the dynamic linker (`/system/bin/linker64` for 64-bit Android). +  -There is another way to load the two ELF objects: -[since 2018](https://android.googlesource.com/platform/bionic/+/8f639a40966c630c64166d2657da3ee641303194) -the dynamic linker can be invoked directly with `exec`. -If passed the filename of an executable, the dynamic linker will load and run the executable itself. -So, instead of executing `path/to/mybinary`, it's possible to execute -`/system/bin/linker64 /absolute/path/to/mybinary` (the linker needs an absolute path). -This is what `termux-exec` does to circumvent the block on executing files in the data -directory - the kernel sees only `/system/bin/linker64` being executed. -This also means that we need to extract [shebangs](https://en.wikipedia.org/wiki/Shebang_(Unix)). So for example, a call to execute: -```sh -./path/to/myscript.sh -``` -where the script has a `#!/path/to/interpreter` shebang, is replaced with: +## Project -```sh -/system/bin/linker64 /path/to/interpreter ./path/to/myscript.sh -``` +**Check the `termux-exec` project info [here](site/pages/en/projects/index.md), including `docs` and `releases` info.** -Implications: +--- -- It's important that `LD_PRELOAD` is kept - see e.g. [this change in sshd](https://github.com/termux/termux-packages/pull/18069). -We could also consider patching this exec interception into the build process of termux packages, so `LD_PRELOAD` would not be necessary for packages built by the termux-packages repository. - -- The executable will be `/system/bin/linker64`. So some programs that inspects the executable name (on itself or other programs) using `/proc/${PID}/exec` or `/proc/${PID}/comm` (where `$(PID}` could be `self`, for the current process) needs to be changed to instead inspect `argv0` of the process instead. See [this llvm driver change](https://github.com/termux/termux-packages/pull/18074) and [this pgrep/pkill change](https://github.com/termux/termux-packages/pull/18075). - -- Statically linked binaries will not work. These are rare in Android and Termux, but zig currently produces statically linked binaries against musl libc. - -- The interception using `LD_PRELOAD` will only work for programs using the [C library wrappers](https://linux.die.net/man/3/execve) for executing a new process, not when using the `execve` system call directly. Luckily most programs do use this. Programs using raw system calls needs to be patched or be run under [proot](https://wiki.termux.com/wiki/PRoot). - -**NOTE**: The above example used `/system/bin/linker64` - on 32-bit systems, the corresponding -path is `/system/bin/linker`. - -**NOTE**: While this circumvents the technical restriction, it still might be considered -violating [Google Play policy](https://support.google.com/googleplay/android-developer/answer/9888379). -So this workaround is not guaranteed to enable Play store distribution of Termux - but it's -worth an attempt, and regardless of Play store distribution, updating the targetSdk is necessary. - -# Problem 2: Shebang paths -A lot of Linux software is written with the assumption that `/bin/sh`, `/usr/bin/env` -and similar file exists. This is not the case on Android where neither `/bin/` nor `/usr/` -exists. - -When building packages for Termux those hard-coded assumptions are patched away - but this -does not help with installing scripts and programs from other sources than Termux packages. - -# Solution 2: Shebang paths -Create an `execve()` wrapper that rewrites calls to execute files under `/bin/` and `/usr/bin` -into the matching Termux executables under `$PREFIX/bin/` and inject that into processes -using `LD_PRELOAD`. - -# How to install -1. Install with `pkg install termux-exec`. -2. Exit your current session and start a new one. -3. From now on shebangs such as `/bin/sh` and `/usr/bin/env python` should work. - -# Where is LD_PRELOAD set? -The `$PREFIX/bin/login` program which is used to create new Termux sessions checks for -`$PREFIX/lib/libtermux-exec.so` and if so sets up `LD_PRELOAD` before launching the login shell. - -Soon, when making a switch to target Android 10+, this will be setup by the Termux app even before -launching any process, as `LD_PRELOAD` will be necessary for anything non-system to execute. +  diff --git a/licenses/termux__termux-exec-package__MIT.md b/licenses/termux__termux-exec-package__MIT.md new file mode 100644 index 0000000..6299e71 --- /dev/null +++ b/licenses/termux__termux-exec-package__MIT.md @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2023 termux + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +- https://opensource.org/licenses/MIT diff --git a/site/pages/en/projects/docs/developer/build/index.md b/site/pages/en/projects/docs/developer/build/index.md new file mode 100644 index 0000000..3e50142 --- /dev/null +++ b/site/pages/en/projects/docs/developer/build/index.md @@ -0,0 +1,141 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@ARK_DOC__VERSION@/developer/build/index.md" +--- + +# termux-exec-package Build Docs + + + +The [`termux-exec`](https://github.com/termux/termux-exec) build instructions are available below. For install instructions, check [`install`](../../install/index.md) docs. + +### Contents + +- [Build Methods](#build-methods) + +--- + +  + + + + + +## Build Methods + +The `termux-exec` package provided by Termux is built from the [`termux/termux-exec`](https://github.com/termux/termux-exec) repository. It can be built with the following methods. + +- [Termux Packages Build Infrastructure](#termux-packages-build-infrastructure) +- [On Device With `make`](#on-device-with-make) + +**The [Termux Packages Build Infrastructure](#termux-packages-build-infrastructure) is the recommended way to build `termux-exec`.** If the `termux-exec` package is built with the [Termux Packages Build Infrastructure](#termux-packages-build-infrastructure), then the Termux variable values in the `Makefile` are dynamically set to the values defined in the [`properties.sh`] file of the build infrastructure by passing them to `make` via the `$TERMUX_PKG_EXTRA_MAKE_ARGS` variable set in the [`packages/termux-exec/build.sh`] file. If `termux-exec` is built with `make` instead, then the hardcoded fallback/default Termux variable values in the `Makefile` will get used during build time, which may affect or break `termux-exec` at runtime if current app/environment is different from the Termux default one (`TERMUX_APP__PACKAGE_NAME=com.termux` and `TERMUX__ROOTFS=/data/data/com.termux/files`). However, if `make` must be used for some reason, and building for a different app/environment than the Termux default, like for a Termux fork or alternate package name/rootfs, then manually update the hardcoded values in the `Makefile` or manually pass the alternate values to the `make` command. + +##   + +  + + + +### Termux Packages Infrastructure + +To build the `termux-exec` package with the [`termux-packages`](https://github.com/termux/termux-packages) build infrastructure, the provided [`build-package.sh`](https://github.com/termux/termux-packages/blob/master/build-package.sh) script can be used. Check the [Build environment](https://github.com/termux/termux-packages/wiki/Build-environment) and [Building packages](https://github.com/termux/termux-packages/wiki/Building-packages) docs for how to build packages. + +#### Default Sources + +To build the `termux-exec` package from its default repository release tag or git branch sources that are used for building the package provided in Termux repositories, just clone the `termux-packages` repository and build. + +```shell +# Clone `termux-packages` repo and switch current working directory to it. +git clone https://github.com/termux/termux-packages.git +cd termux-packages + +# (OPTIONAL) Run termux-packages docker container if running off-device. +./scripts/run-docker.sh + +# Force build package and download dependencies from Termux packages repositories. +./build-package.sh -f -I termux-exec +``` + +#### Local Sources + +To build the `termux-exec` package from its local sources or a pull request branch, clone the `termux-packages` repository, clone/create the `termux-exec` repository locally, make required changes to the [`packages/termux-exec/build.sh`] file to update the source url and then build. + +Check [Build Local Package](https://github.com/termux/termux-packages/wiki/Building-packages#build-local-package) and [Package Build Local Source URLs](https://github.com/termux/termux-packages/wiki/Creating-new-package#package-build-local-source-urls) docs for more info on how to building packages from local sources.* + +```shell +# Clone `termux-packages` repo and switch current working directory to it. +git clone https://github.com/termux/termux-packages.git +cd termux-packages + +# Update `$TERMUX_PKG_SRCURL` variable in `packages/termux-exec/build.sh`. +# We use `file:///path/to/source/dir` format for the local source URL. +TERMUX_PKG_SRCURL=file:///home/builder/termux-packages/sources/termux-exec +TERMUX_PKG_SHA256=SKIP_CHECKSUM + +# Clone/copy `termux-exec` repo at `termux-packages/sources/termux-exec` +# directory. Make sure current working directory is root directory of +# termux-packages repo when cloning. +git clone https://github.com/termux/termux-exec.git sources/termux-exec + +# (OPTIONAL) Manually switch to different (pull) branch that exists on +# origin if required, or to the one defined in $TERMUX_PKG_GIT_BRANCH +# variable of build.sh file, as it will not be automatically checked out. +# By default, the repo default/current branch that's cloned +# will get built, which is usually `master` or `main`. +# Whatever is the current state of the source directory will +# be built as is, including any uncommitted changes to current +# branch. +(cd sources/termux-exec; git checkout ) + +# (OPTIONAL) Run termux-packages docker container if running off-device. +./scripts/run-docker.sh + +# Force build package and download dependencies from Termux packages repositories. +./build-package.sh -f -I termux-exec +``` + +##   + +  + + + +### On Device With `make` + +To build `termux-exec` package on the device inside the Termux app with [`make`](https://www.gnu.org/software/make), check below. Do not use a PC to build the package as PC architecture may be different from target device architecture and the `clang` compiler wouldn't have been patched like Termux provided one is so that built packages are compatible with Termux, like patches done for `DT_RUNPATH`. + +```shell +# Install dependencies. +pkg install clang git make termux-create-package + +# Clone/copy `termux-exec` repo at `termux-exec` directory and switch +# current working directory to it. +git clone https://github.com/termux/termux-exec.git termux-exec +cd termux-exec + +# Whatever is the current state of the `termux-exec` directory will be built. +# If required, manually switch to different (pull) branch that exists on origin. +git checkout + +# Remove any existing deb files in current directory. +rm -f termux-exec_*.deb + +# Build deb file for the architecture of the host device/clang compiler. +make deb + +# Install. +# We use shell * glob expansion to automatically select the deb file +# regardless of `__.deb` suffix, that's why existing +# deb files were deleted earlier in case any existed with the wrong version. +dpkg -i termux-exec_*.deb +``` + +--- + +  + + + + + +[`packages/termux-exec/build.sh`]: https://github.com/termux/termux-packages/blob/master/packages/termux-exec/build.sh +[`properties.sh`]: https://github.com/termux/termux-packages/blob/master/scripts/properties.sh diff --git a/site/pages/en/projects/docs/developer/contribute/index.md b/site/pages/en/projects/docs/developer/contribute/index.md new file mode 100644 index 0000000..a0c5326 --- /dev/null +++ b/site/pages/en/projects/docs/developer/contribute/index.md @@ -0,0 +1,51 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@ARK_DOC__VERSION@/developer/contribute/index.md" +--- + +# termux-exec-package Contribute Docs + + + +These docs are meant for you if you want to contribute to the [`termux/termux-exec`](https://github.com/termux/termux-exec) repository. + +### Contents + +- [Commit Messages Guidelines](#commit-messages-guidelines) + +--- + +  + + + + + +## Commit Messages Guidelines + +Commit messages **must** use the [Conventional Commits](https://www.conventionalcommits.org) spec so that changelogs can be automatically generated when [releases](../../../releases/index.md) are made as per the [Keep a Changelog](https://github.com/olivierlacan/keep-a-changelog) spec by the [`create-conventional-changelog`](https://github.com/termux/create-conventional-changelog) script, check its repository for further details on the spec. + +**The first letter for `type` and `description` must be capital and description should be in the present tense.** The space after the colon `:` is necessary. For a breaking change, add an exclamation mark `!` before the colon `:` as an indicator, and it will also cause the change to be automatically highlighted in the changelog. + +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +**Only the `types` listed below must be used exactly as they are used in the changelog headings.** For example, `Added: Add foo`, `Added|Fixed: Add foo and fix bar`, `Changed!: Change baz as a breaking change`, etc. You can optionally add a scope as well, like `Fixed(docs): Fix some bug`. **Do not use anything else as type, like `add` instead of `Added`, or `chore`, etc.** + +- **Added** for new additions or features. +- **Changed** for changes in existing functionality. +- **Deprecated** for soon-to-be removed features. +- **Fixed** for any bug fixes. +- **Removed** for now removed features. +- **Reverted** for changes that were reverted. +- **Patched** for patches done for specific builds. +- **Security** in case of vulnerabilities. +- **Release** for when a new release is made. + +--- + +  diff --git a/site/pages/en/projects/docs/developer/index.md b/site/pages/en/projects/docs/developer/index.md new file mode 100644 index 0000000..08386d0 --- /dev/null +++ b/site/pages/en/projects/docs/developer/index.md @@ -0,0 +1,19 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@ARK_DOC__VERSION@/developer/index.md" +--- + +# termux-exec-package Developer Docs + + + +These docs are meant for the developers, maintainers and contributors of the [`termux/termux-exec`](https://github.com/termux/termux-exec) repository and its forks. + +### Contents + +- [Build](build/index.md) +- [Test](test/index.md) +- [Contribute](contribute/index.md) + +--- + +  diff --git a/site/pages/en/projects/docs/developer/test/index.md b/site/pages/en/projects/docs/developer/test/index.md new file mode 100644 index 0000000..9601644 --- /dev/null +++ b/site/pages/en/projects/docs/developer/test/index.md @@ -0,0 +1,81 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@ARK_DOC__VERSION@/developer/test/index.md" +--- + +# termux-exec-package Test Docs + + + +The [`termux-exec`](https://github.com/termux/termux-exec) can be tested with [`termux-exec-tests`](https://github.com/termux/termux-exec/blob/master/tests/termux-exec-tests.in). + +Install the updated `termux-exec` package and then start a new shell so that changes for updated library get loaded. + +Update `bash termux-tools termux-am` packages to the latest version, otherwise tests will fail. Install Termux:API app and latest `termux-api` package to test them as well. + +To show help, run `"${TERMUX__PREFIX:-$PREFIX}/libexec/installed-tests/termux-exec/termux-exec-tests" --help`. + +To run all tests, run `TERMUX_EXEC__LOG_LEVEL=1 "${TERMUX__PREFIX:-$PREFIX}/libexec/installed-tests/termux-exec/termux-exec-tests" -vv all`. You can optionally run only `unit` or `runtime` tests as well. +- The `unit` tests test different units/components of the `termux-exec` source code. +- The `runtime` tests test the runtime execution of `termux-exec` binaries and scripts, and also for other Termux packages/commands to ensure proper functioning of the Termux execution environment. + +To only run `termux-exec` package specific tests and not other Termux packages/commands, pass `--only-termux-exec-tests`. +To skip `termux-core` package tests, pass `--skip-termux-core-tests`, as under normal circumstances with Termux app in foreground, tests take `~5min` to run depending on device. + +Make sure to grant Termux app `Draw over apps` permission as otherwise `termux-am` tests will fail. + +Two variants of each test binary is compiled. +- With `fsanitize` enabled with the `-fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer` flags that contain `-fsanitize` in filename +- Without `fsanitize` enabled that contain `-nofsanitize` in filename. + +The `runtime-binary-tests` is also additionally compiled for Android API level `28` by `termux-exec` [`build.sh`](https://github.com/termux/termux-packages/blob/master/packages/termux-exec/build.sh) if `TERMUX_PKG_API_LEVEL` is `< 28` to test APIs that are only available on higher Android versions like `fexecve()`. When `termux-exec-tests` is executed, the `run_runtime_binary_tests()` function dynamically calls the `runtime-binary-tests` variant that would be supported by the host device. + +This is requires because `fsanitize` does not work on all Android versions/architectures properly and may crash with false positives with the `AddressSantizier: SEGV on unknown address` error, like Android `7` (always crashes) and `x86_64` (requires loop to trigger as occasional crash), even for a source file compiled with an empty `main()` function. + +To enable `AddressSantizier` while running `termux-exec-tests`, pass `-f`. To also enable `LeakSanitizer`, pass `-l` as well, but if it is not supported on current device, the `termux-exec-tests` will error out with `AddressSantizier: detect_leaks is not supported on this platform`. + +If you get `CANNOT LINK EXECUTABLE *: library "libclang_rt.asan-aarch64.so" not found`, like on Android `7`, you will need to install the `libcompiler-rt` package to get the `libclang_rt.asan-aarch64.so` dynamic library required for `AddressSantizier` if passing `-f`. Export library file path with `export LD_LIBRARY_PATH="${TERMUX__PREFIX:-$PREFIX}/lib/clang/17/lib/linux"` before running tests. + +--- + +  + + + + + +## Help + +``` +termux-exec-tests is a script that run tests for the termux-exec. + + +Usage: + termux-exec-tests [command_options] + +Available commands: + unit Run unit tests. + runtime Run runtime on-device tests. + all Run all tests. + +Available command_options: + [ -h | --help ] Display this help screen. + [ --version ] Display version. + [ -q | --quiet ] Set log level to 'OFF'. + [ -v | -vv | -vvv | -vvvvv ] + Set log level to 'DEBUG', 'VERBOSE', + 'VVERBOSE' and 'VVVERBOSE'. + [ -f ] Use fsanitize binaries for AddressSanitizer. + [ -l ] Detect memory leaks with LeakSanitizer. + Requires '-f' to be passed. + [ --ld-preload= ] The path to 'libtermux-exec.so'. + [ --no-clean ] Do not clean test files on failure. + [ --only-termux-exec-tests ] + Only run 'termux-exec' package tests. + [ --skip-termux-core-tests ] + Skip 'termux-core' package tests. + [ --tests-path= ] The path to installed-tests directory. +``` + +--- + +  diff --git a/site/pages/en/projects/docs/index.md b/site/pages/en/projects/docs/index.md new file mode 100644 index 0000000..03e10a0 --- /dev/null +++ b/site/pages/en/projects/docs/index.md @@ -0,0 +1,26 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@ARK_DOC__VERSION@/index.html" +ark__replacement_strings: + - target: "../releases/index.md" + replacement: "@ARK_PAGE__URL@/../../../releases/index.html" +--- + +# termux-exec-package Docs + + + +The [`termux-exec`](https://github.com/termux/termux-exec) package provides a shared library that is meant to be preloaded with [`LD_PRELOAD`](https://man7.org/linux/man-pages/man8/ld.so.8.html) for proper functioning of the Termux execution environment. + +### Contents + +- [Releases](../releases/index.md) +- [Install](install/index.md) +- [Usage](usage/index.md) +- [Technical](technical/index.md) +- [Developer](developer/index.md) + - [Build](developer/build/index.md) + - [Test](developer/test/index.md) + - [Contribute](developer/contribute/index.md) +- [License](https://github.com/termux/termux-exec/blob/master/LICENSE) + +--- diff --git a/site/pages/en/projects/docs/install/index.md b/site/pages/en/projects/docs/install/index.md new file mode 100644 index 0000000..f4e5e69 --- /dev/null +++ b/site/pages/en/projects/docs/install/index.md @@ -0,0 +1,45 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@ARK_DOC__VERSION@/install/index.md" +--- + +# termux-exec-package Install Docs + + + +The [`termux-exec`](https://github.com/termux/termux-exec) install instructions are available below. For build instructions, check [`build`](../developer/build/index.md) docs. + +### Contents + +- [Install Sources](#install-sources) + +--- + +  + + + + + +## Install Sources + +`termux-exec` can be installed from the following sources. + +- [Termux Packages Repository](#termux-packages-repository) + +##   + +  + + + +### Termux Packages Repository + +To install `termux-exec` from the [`main` channel](https://github.com/termux/termux-packages/blob/master/packages/termux-exec/build.sh) of the [Termux packages repository](https://packages.termux.dev), run the following commands. + +```shell +pkg install termux-exec +``` + +--- + +  diff --git a/site/pages/en/projects/docs/technical/index.md b/site/pages/en/projects/docs/technical/index.md new file mode 100644 index 0000000..6a13fba --- /dev/null +++ b/site/pages/en/projects/docs/technical/index.md @@ -0,0 +1,135 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@ARK_DOC__VERSION@/technical/index.md" +--- + +# termux-exec-package Technical Docs + + + +The [`termux-exec`](https://github.com/termux/termux-exec) is a shared library that is meant to be preloaded with [`$LD_PRELOAD`](https://man7.org/linux/man-pages/man8/ld.so.8.html) for proper functioning of the Termux execution environment. + +The following functions are overridden. + +- [`exec()`](#exec) + +--- + +  + + + + + +## `exec()` + +The `exec()` family of functions are [declared in `unistd.h`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/include/unistd.h;l=92-100) and [implemented by `exec.cpp`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/bionic/exec.cpp) in android [`bionic`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/README.md) `libc` library. The `exec()` functions are wrappers around the [`execve()`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/SYSCALLS.TXT;l=68) system call listed in [`syscalls(2)`](https://man7.org/linux/man-pages/man2/syscalls.2.html) provided by the [android/linux kernel](https://cs.android.com/android/kernel/superproject/+/ebe69964:common/include/linux/syscalls.h;l=790), which can also be directly called with the [`syscall(2)`](https://man7.org/linux/man-pages/man2/syscall.2.html) library function [declared in `unistd.h`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/include/unistd.h;l=308). Note that there is also a `execve()` wrapper in `unistd.h` around the `execve()` system call. The `termux-exec` overrides the entire `exec()` family of functions, but will not override direct calls to the `execve()` system call via `syscall(2)`, which is usually not directly called by programs. + +**See Also:** + +- [exec (system call) wiki](https://en.wikipedia.org/wiki/Exec_(system_call)) +- [`unistd.h` POSIX spec](https://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html) +- [`execve` POSIX spec](https://pubs.opengroup.org/onlinepubs/7908799/xsh/execve.html) +- [`execve(2)` linux man](https://man7.org/linux/man-pages/man2/execve.2.html) +- [`exec(3)` linux man](https://man7.org/linux/man-pages/man3/exec.3.html) +- [`exec(3p)` linux man](https://man7.org/linux/man-pages/man3/exec.3p.html) + +  + + + +The `termux-exec` overrides the `exec()` family of functions to solve the following issues when exec-ing files in Termux. + +- [App Data File Execute Restrictions](#app-data-file-execute-restrictions) +- [Linux vs Termux `bin` paths](#linux-vs-termux-bin-paths) + +  + + + +### App Data File Execute Restrictions + +Android `>= 10` as part of `W^X` restrictions with the [`0dd738d8`](https://cs.android.com/android/_/android/platform/system/sepolicy/+/0dd738d810532eb41ad8d90520156212ce756648) commit via [SeLinux](https://source.android.com/docs/security/features/selinux) policies removed the `untrusted_app*` domains/process context type assigned to untrusted third party app processes that use [`targetSdkVersion`](https://developer.android.com/guide/topics/manifest/uses-sdk-element#target) `>= 29` to `exec()` their app data files that are assigned the `app_data_file` file context type, like under the `/data/data/` (for user `0`) directory. Two backward compatibility domains were also added for which `exec()` was still allowed, the `untrusted_app_25` domain for apps that use `targetSdkVersion` `<= 25` and `untrusted_app_27` that use `targetSdkVersion` `26-28`. For all `untrusted_app*` domains, `dlopen()` on app data files is still allowed. + +Check [`App Data File Execute Restrictions` android docs](https://github.com/agnostic-apollo/Android-Docs/blob/master/site/pages/en/projects/docs/apps/processes/app-data-file-execute-restrictions.md) for more information on the `W^X` restrictions, including that apply to other app domains. + +While there is merit to prevent execution of untrusted code in writable storage as a general principle, this prevents using Termux and Android as a general purpose computing device, where it should be possible for users to download executable binaries and scripts from trusted locations or compile it locally and then execute it, after user explicitly grants the app the permission to do so with some kind of runtime/development permission provided by Android. + +**See Also:** + +- [`issuetracker#128554619`](https://issuetracker.google.com/issues/128554619) +- [`termux/termux-app#1072`: No more exec from data folder on targetAPI >= Android Q](https://github.com/termux/termux-app/issues/1072) +- [`termux/termux-app#2155`: Revisit the Android W^X problem](https://github.com/termux/termux-app/issues/2155) + +  + +#### System Linker Exec Solution + +Check [`System Linker Exec` android docs](https://github.com/agnostic-apollo/Android-Docs/blob/master/site/pages/en/projects/docs/apps/processes/app-data-file-execute-restrictions.md#system-linker-exec) for detailed info for the solution to bypass `W^X` restrictions. + +The [dynamic linker](https://en.wikipedia.org/wiki/Dynamic_linker) is the part of the operating system that loads and links the shared libraries needed by an executable when it is executed. The kernel is normally responsible for loading both the executable and the dynamic linker. When a [`execve()` system call](https://en.wikipedia.org/wiki/Exec_(system_call)) is made for an [`ELF`](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#Program_header) executable, the kernel loads the executable file, then reads the path to the dynamic linker from the `PT_INTERP` entry in [`ELF` program header table](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#Program_header) and then attempts to load and execute this other executable binary for the dynamic linker, which then loads the initial executable image and all the dynamically-linked libraries on which it depends and starts the executable. For binaries built for Android, `PT_INTERP` specifies the path to `/system/bin/linker64` for 64-bit binaries and `/system/bin/linker` for 32-bit binaries. You can check `ELF` file headers with the [`readelf`](https://www.man7.org/linux/man-pages/man1/readelf.1.html) command, like `readelf --program-headers --dynamic /path/to/executable`. + +The system provided `linker` at `/system/bin/linker64` on 64-bit Android and `/system/bin/linker` on 32-bit Android can also be passed an absolute path to an executable file on Android `>= 10` for it to execute, even if the executable file itself cannot be executed directly from the app data directory. Note that some 64-devices have 32-bit Android. + +An ELF file at `/data/data/com.foo/executable` can be executed with: + +```shell +/system/bin/linker64 /data/data/com.foo/executable [args] +``` + +A script file at `/data/data/com.foo/script.sh` that has the `#!/path/to/interpreter` [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) can be executed with: + +```sh +/system/bin/linker64 /path/to/interpreter /data/data/com.foo/script.sh [args] +``` + +This is possible because when a file is executed with the system linker, the kernel/SeLinux only sees the `linker` binary assigned the `system_linker_exec` file context type being executed by the app process and not the `*app_data_file` being executed by the linker. + +Support in Android `linker` to execute files was added in Android `10`, so this method cannot be used on older Android versions, like for some system app domains. For `untrusted_app*` domains, this is not an issue since they can execute files directly on Android `< 10`. + +- https://cs.android.com/android/_/android/platform/bionic/+/8f639a40966c630c64166d2657da3ee641303194 +- https://cs.android.com/android/_/android/platform/bionic/+/refs/tags/android-10.0.0_r1:linker/linker_main.cpp + +#### System Linker Exec Issues + +1. The `$LD_PRELOAD` environment variable must be exported and must contain the path to the `termux-exec` library before any app data file is executed, but not for android system binaries under `/system/bin`. It needs to be set for all entry points into termux, including when connecting to a `sshd` server, see [`termux/termux-packages#18069`](https://github.com/termux/termux-packages/pull/18069). We can also consider patching exec interception into the build process of termux packages, so `$LD_PRELOAD` would not be necessary for packages built by the `termux-packages` repository. + +2. The executable file will be `/system/bin/linker64` and not the ELF file meant to be executed, so some programs that inspect the executable name with [`proc`](https://man7.org/linux/man-pages/man5/proc.5.html) files like `/proc//exe` or `/proc//comm` will see the wrong name. For packages that read `/proc/self/exe` file of their own process, the `termux-exec` exports the [`$TERMUX_EXEC__PROC_SELF_EXE`](../usage/index.md#termux_exec__proc_self_exe) environment variable with the absolute path to ELF file being executed so that such packages can be patched to read it first instead, however, this will not work if reading `exe` file of other processes as `TERMUX_EXEC__PROC_SELF_EXE` will only be set for the current process, and not others. Programs like `pgrep`/`pkill` that match process name from its command, will have to be patched to either do full matching (`-f`/`--full`) OR preferably as the linker binary is normally not executed, so during matching to skip the first argument if its for the system linker and second arg is for an app data file under `TERMUX_APP__DATA_DIR` and `TERMUX_EXEC__PROC_SELF_EXE` is set for itself to indicate its running in a `system_linker_exec` environment. See also [`termux/termux-packages#18069`](https://github.com/termux/termux-packages/pull/18075). + +3. Statically linked binaries will not work. These are rare in Android and Termux, but `zig` currently produces statically linked binaries against `musl` `libc`. + +4. Packages that call the `execve()` system call directly will need to be patched to use one of the `exec()` family wrappers or they should be run under [`proot`](https://wiki.termux.com/wiki/PRoot). + +5. This solution is not compliant with Google PlayStore policies as executing code downloaded (or compiled) at runtime from sources outside the Google Play Store, like not packed inside the apk is not allowed. However, if even apps using this like Termux are not approved to be uploaded to PlayStore, it at least allows using currently latest `targetSdkVersion` `= 34` to target Android `14`. + + > An app distributed via Google Play may not modify, replace, or update itself using any method other than Google Play's update mechanism. Likewise, an app may not download executable code (such as dex, JAR, .so files) from a source other than Google Play. This restriction does not apply to code that runs in a virtual machine or an interpreter where either provides indirect access to Android APIs (such as JavaScript in a webview or browser). + > Apps or third-party code, like SDKs, with interpreted languages (JavaScript, Python, Lua, etc.) loaded at run time (for example, not packaged with the app) must not allow potential violations of Google Play policies. + + - https://support.google.com/googleplay/android-developer/answer/9888379?hl=en + +##   + +  + + + +### Linux vs Termux `bin` paths + +A lot of Linux software is written with the assumption that rootfs is at `/` and system binaries under the `/bin` or `/usr/bin` directories and the system binaries for script [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) interpreter paths exist at paths like `/bin/sh`, `/usr/bin/env`, etc. + +However, on Android the `/bin` path does not exist on Android `<= 8.1`. On Android `>= 9`, `/bin` is a [symlink to `/system/bin` directory](https://cs.android.com/android/_/android/platform/system/core/+/refs/tags/android-9.0.0_r1:rootdir/init.rc;l=48) added via [`ff1ef9f2`](https://cs.android.com/android/_/android/platform/system/core/+/ff1ef9f2b10d98131ea8945c642dd8388d9b0250). The `/usr` path does not exist on any Android version. + +But the `/system/bin` directory is for the path to android system binaries, not the ones provided by Termux. The rootfs for the linux environment provided by apps like Termux is under their app data directory instead, like under the `/data/data/` (for user `0`) directory or `/data/user//` for other secondary users. For packages compiled for the main Termux app, it is at `/data/data/com.termux/files` and its `bin` path is at `/data/data/com.termux/files/usr/bin`. Check [Termux filesystem layout](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout) for more info. + +When packages are built for Termux with the [`termux-packages`](https://github.com/termux/termux-packages) build infrastructure, the harcoded paths for `/` rootfs in package sources are patched and replaced with the rootfs for Termux, but if `/bin/*` or `/usr/bin/*` paths are executed, like via the shell or if they are set in scripts or programs downloaded from outside the Termux packages repos or written by users themselves, they will either fail to execute with `No such file or directory` errors or will execute the android system binaries under `/system/bin/*` if the same filename exists, instead of executing binaries under the Termux `bin` path. + +  + +#### Solution + +The `termux-exec` if set in `$LD_PRELOAD` environment variable overrides the `exec()` family of functions so that if the executable path is under the `/bin/*` or `/usr/bin/*` directories or if a script that is being executed has the interpreter path set to a path under `/bin/*` or `/usr/bin/*` directories, then the `*/bin/` prefix in the path is replaced with the termux `$TERMUX__PREFIX/bin/` prefix, where `$TERMUX__PREFIX` is the environment variable exported by the Termux app. If `$TERMUX__PREFIX` is not exported or is not a valid absolute path, then the default `TERMUX__PREFIX` set by the `Makefile` during `termux-exec` build time is used instead as the Termux prefix path. + +An alternate solution, especially in case `$LD_PRELOAD` may not be set is to run [`termux-fix-shebang`](https://github.com/termux/termux-tools/blob/master/scripts/termux-fix-shebang.in) on the script file before executing them. This would have to be done when a script is initially installed/written and whenever its upgraded. + +--- + +  diff --git a/site/pages/en/projects/docs/usage/index.md b/site/pages/en/projects/docs/usage/index.md new file mode 100644 index 0000000..3ba5633 --- /dev/null +++ b/site/pages/en/projects/docs/usage/index.md @@ -0,0 +1,413 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/docs/@DOCS__VERSION@/usage/index.md" +--- + +# termux-exec-package Usage Docs + + + +The [`termux-exec`](https://github.com/termux/termux-exec) package provides a shared library that is meant to be preloaded by exporting [`LD_PRELOAD=/data/data/com.termux/files/usr/lib/libtermux-exec.so`](https://man7.org/linux/man-pages/man8/ld.so.8.html) in shells for proper functioning of the Termux execution environment. This is automatically done by Termux in the [`login`](https://github.com/termux/termux-tools/blob/v1.40.1/scripts/login.in#L42-L45) script, but currently not for shells started by plugins, check [here](https://github.com/termux/termux-tasker#termux-environment) for more info. + +Note that if exporting `LD_PRELOAD` or updating the `termux-exec` library, the current shell will not automatically load the updated library as any libraries that are to be loaded are only done when process is started. If unsetting `LD_PRELOAD`, the current shell will not automatically unload the library either. Changes to `LD_PRELOAD` requires at least one nested `exec()` for changes to take effect, i.e a new nested shell needs to be started and then any new calls/executions in the nested shell will be hooked by the library set it `LD_PRELOAD`. + +### Contents + +- [Input Environment Variables](#input-environment-variables) +- [Output Environment Variables](#ouput-environment-variables) +- [Processed Environment Variables](#processed-environment-variables) + +--- + +  + + + + + +## Input Environment Variables + +The `termux-exec` uses the following environment variables as input if required. + +*For variables with type `bool`, the values `1`, `true`, `on`, `yes`, `y` are parsed as `true` and the values `0`, `false`, `off`, `no`, `n` are parsed as `false`, and for any other value the default value will be used.* + +- [`TERMUX_APP__DATA_DIR`](#termux_app__data_dir) +- [`TERMUX_APP__LEGACY_DATA_DIR`](#termux_app__legacy_data_dir) +- [`TERMUX__PREFIX`](#termux__prefix) +- [`TERMUX__SE_PROCESS_CONTEXT`](#termux__se_process_context) +- [`TERMUX_EXEC__LOG_LEVEL`](#termux_exec__log_level) +- [`TERMUX_EXEC__INTERCEPT_EXECVE`](#termux_exec__intercept_execve) +- [`TERMUX_EXEC__SYSTEM_LINKER_EXEC`](#termux_exec__system_linker_exec) +- [`TERMUX_EXEC__TESTS__LOG_LEVEL`](#termux_exec__tests__log_level) + +  + + + +### TERMUX_APP__DATA_DIR + +The non-legacy [Termux app data directory path](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-private-app-data-directory) (`/data/user//` or `/mnt/expand//user/0/`) that is assigned by Android for all Termux app data returned for the [`ApplicationInfo.dataDir`](https://developer.android.com/reference/android/content/pm/ApplicationInfo#dataDir) call, that contains the [Termux project directory](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-project-directory) (`TERMUX__PROJECT_DIR`), and optionally the [Termux rootfs directory](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-rootfs-directory) (`TERMUX__ROOTFS`). The value is automatically exported by the Termux app for app version `>= 0.119.0`. + +**Type:** `string` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** `/data/user/0/com.termux` if Termux app is running under primary user `0`. + +**Assigned values:** + +- An absolute path with max length `TERMUX_APP__DATA_DIR___MAX_LEN` (`69`) including the null `\0` terminator. + +If `TERMUX_APP__DATA_DIR` environment variable is not set or value is not valid, then the build value set in [`properties.sh`] file for the app data directory with which `termux-exec` package is compiled with is used, which defaults to `/data/data/@TERMUX_APP__PACKAGE_NAME@`. + +The `TERMUX_APP__DATA_DIR___MAX_LEN` is defined in [`termux_files.h`](https://github.com/termux/termux-exec/blob/0281129f/src/termux/termux_files.h) and it is the internal buffer length used by `termux-exec` for storing Termux app data directory path and the buffer lengths of all other Termux paths under the app data directory is based on it. The value `69` is the maximum value that will fit the requirement for a valid Android app data directory path, check [termux file path limits](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#file-path-limits) docs for more info. **Packages compiled for Termux must ensure that the `TERMUX_APP__DATA_DIR` value used during compilation is `< TERMUX_APP__DATA_DIR___MAX_LEN`.** + +##   + +  + + + +### TERMUX_APP__LEGACY_DATA_DIR + +The legacy [Termux app data directory path](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-private-app-data-directory) (`/data/data/`) assigned by Android for all Termux app data, that contains the [Termux project directory](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-project-directory) (`TERMUX__PROJECT_DIR`), and optionally the [Termux rootfs directory](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-rootfs-directory) (`TERMUX__ROOTFS`). The value is automatically exported by the Termux app for app version `>= 0.119.0`. + +**Type:** `string` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** `/data/data/com.termux` if Termux app is running under primary user `0`. + +**Assigned values:** + +- An absolute path with max length `TERMUX_APP__DATA_DIR___MAX_LEN` (`69`) including the null `\0` terminator. + +If `TERMUX_APP__LEGACY_DATA_DIR` environment variable is not set or value is not valid, then the build value set in [`properties.sh`] file for the app data directory with which `termux-exec` package is compiled with is used, which defaults to `/data/data/@TERMUX_APP__PACKAGE_NAME@`. If the build value is a non-legacy path (`/data/user//` or `/mnt/expand//user/0/`), then it is automatically converted to a legacy path. + +The `TERMUX_APP__DATA_DIR___MAX_LEN` is defined in [`termux_files.h`](https://github.com/termux/termux-exec/blob/0281129f/src/termux/termux_files.h) and it is the internal buffer length used by `termux-exec` for storing Termux app data directory path and the buffer lengths of all other Termux paths under the app data directory is based on it. The value `69` is the maximum value that will fit the requirement for a valid Android app data directory path, check [termux file path limits](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#file-path-limits) docs for more info. **Packages compiled for Termux must ensure that the `TERMUX_APP__DATA_DIR` value used during compilation is `< TERMUX_APP__DATA_DIR___MAX_LEN`.** + +##   + +  + + + +### TERMUX__PREFIX + +The [Termux prefix directory path](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-prefix-directory) under or equal to the [Termux rootfs directory](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#termux-rootfs-directory) (`TERMUX__ROOTFS`) where all Termux packages data is installed. The value is automatically exported by the Termux app for app version `>= 0.119.0`. + +**Type:** `string` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** `/data/data/com.termux/files/usr` + +**Assigned values:** + +- An absolute path with max length `TERMUX__PREFIX_DIR___MAX_LEN` (`90`) including the null `\0` terminator. + +If `TERMUX__PREFIX` environment variable is not set or value is not valid, then the build value set in [`properties.sh`] file for the app data directory with which `termux-exec` package is compiled with is used, which defaults to `/data/data/@TERMUX_APP__PACKAGE_NAME@/files/usr`. If the build value is not accessible `termux-exec` hooks will return with an error and `errno` should be set that is set by the [`access()`](https://man7.org/linux/man-pages/man2/access.2.html) call. + +The `TERMUX__PREFIX_DIR___MAX_LEN` is defined in [`termux_files.h`](https://github.com/termux/termux-exec/blob/0281129f/src/termux/termux_files.h) and it is the internal buffer length used by `termux-exec` for storing Termux prefix directory path. The value `90` is the maximum value that will fit the requirement for a valid Termux prefix directory path, check [termux file path limits](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#file-path-limits) docs for more info. **Packages compiled for Termux must ensure that the `TERMUX__PREFIX` value used during compilation is `< TERMUX__PREFIX_DIR___MAX_LEN`.** + +##   + +  + + + +### TERMUX__SE_PROCESS_CONTEXT + +The SeLinux process context of the Termux app process and its child processes. The value is automatically exported by the Termux app for app version `>= 0.119.0`. + +This is used while deciding whether to use `system_linker_exec` if [`TERMUX_EXEC__SYSTEM_LINKER_EXEC`](#termux_exec__system_linker_exec) is set to `enabled`. + +**Type:** `string` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** `u:r:untrusted_app_27:s0:cXXX,cXXX,c512,c768` if Termux app is running under primary user `0` and using [`targetSdkVersion`](https://developer.android.com/guide/topics/manifest/uses-sdk-element#target) `= 28` where `XXX` would be for the app uid for the [categories](https://github.com/agnostic-apollo/Android-Docs/blob/master/site/pages/en/projects/docs/os/selinux/security-context.md#categories) component. + +**Assigned values:** + +- A valid Android SeLinux process context that matches `REGEX__PROCESS_CONTEXT`: +`^u:r:[^\n\t\r :]+:s0(:c[0-9]+,c[0-9]+(,c[0-9]+,c[0-9]+)?)?$` + +If `TERMUX__SE_PROCESS_CONTEXT` is not set or value is not valid, then the process context is read from the `/proc/self/attr/current` file. + +The `REGEX__PROCESS_CONTEXT` is defined in [`selinux_utils.h`](https://github.com/termux/termux-exec/blob/0281129f/src/os/selinux_utils.h), check its field docs for more info on the format of the an Android SeLinux process context. + +**See Also:** + +- [Security Context](https://github.com/agnostic-apollo/Android-Docs/blob/master/site/pages/en/projects/docs/os/selinux/security-context.md) +- [`untrusted_app` process context type](https://github.com/agnostic-apollo/Android-Docs/blob/master/site/pages/en/projects/docs/os/selinux/context-types.md#untrusted_app) + +##   + +  + + + +### TERMUX_EXEC__LOG_LEVEL + +The log level for `termux-exec`. + +Normally, `termux-exec` does not log anything at log level `1` (`NORMAL`) for hooks even and will require setting log level to `>= 2` (`DEBUG`) to see log messages. + +**Type:** `int` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** `1` + +**Supported values:** + +- `0` (`OFF`) - Log nothing. + +- `1` (`NORMAL`) - Log error, warn and info messages and stacktraces. + +- `2` (`DEBUG`) - Log debug messages. + +- `3` (`VERBOSE`) - Log verbose messages. + +- `4` (`VVERBOSE`) - Log very verbose messages. + +- `5` (`VVVERBOSE`) - Log very very verbose messages. + +##   + +  + + + +### TERMUX_EXEC__INTERCEPT_EXECVE + +Whether `termux-exec` should intercept `execve()` wrapper calls [declared in `unistd.h`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/include/unistd.h;l=95) and [implemented by `exec.cpp`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/bionic/exec.cpp;l=187) in android [`bionic`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/README.md) `libc` library around the [`execve()`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/SYSCALLS.TXT;l=68) system call listed in [`syscalls(2)`](https://man7.org/linux/man-pages/man2/syscalls.2.html) provided by the [linux kernel](https://cs.android.com/android/kernel/superproject/+/ebe69964:common/include/linux/syscalls.h;l=790). + +If enabled, then Termux specific logic will run to solve the issues for exec-ing files in Termux that are listed in [`exec()` technical docs](../technical.md#exec) before calling `execve()` system call. If not enabled, then `execve()` system call will be called directly instead. + +The other wrapper functions in the `exec()` family of functions declared in `unistd.h` are always intercepted to solve some other issues on older Android versions, check [`libc/bionic/exec.cpp`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/bionic/exec.cpp) git history. + +**Type:** `bool` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** `true` + +**Supported values:** + +- `true` - Intercept `execve()` enabled. + +- `false` - Intercept `execve()` disabled. + +##   + +  + + + +### TERMUX_EXEC__SYSTEM_LINKER_EXEC + +Whether to use [System Linker Exec Solution](../technical.md#system-linker-exec-solution), like to bypass [App Data File Execute Restrictions](../technical.md#app-data-file-execute-restrictions). + +**Type:** `string` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** null + +**Supported values:** + +- `disable` - The `system_linker_exec` will be disabled. + +- `enable` - The `system_linker_exec` will be enabled but only if required. + +- `force` - The `system_linker_exec` will be force enabled even if not required and is supported. + +This is implemented by `should_system_linker_exec()` in [`exec.c`](https://github.com/termux/termux-exec/blob/0281129f/src/exec/exec.c). + +If `disable` is set, then `system_linker_exec` will never be used and the default `direct` execution type will be used. + +If `enable` is set, then `system_linker_exec` will only be used if: +- `system_linker_exec` is required to bypass [App Data File Execute Restrictions](../technical.md#app-data-file-execute-restrictions), i.e device is running on Android `>= 10`. +- Effective user does not equal root (`0`) and shell (`2000`) user (used for [`adb`](https://developer.android.com/tools/adb)). +- [`TERMUX__SE_PROCESS_CONTEXT`](#TERMUX__SE_PROCESS_CONTEXT) does not start with `PROCESS_CONTEXT_PREFIX__UNTRUSTED_APP_25` (`u:r:untrusted_app_25:`) and `PROCESS_CONTEXT_PREFIX__UNTRUSTED_APP_27` (`u:r:untrusted_app_27:`) for which restrictions are exempted. For more info on them, check [`selinux_utils.h`](https://github.com/termux/termux-exec/blob/0281129f/src/os/selinux_utils.h). +- Executable or interpreter path is under [`TERMUX_APP__DATA_DIR`] or [`TERMUX_APP__LEGACY_DATA_DIR`] directory. + +If `force` is set, then `system_linker_exec` will only be used if: +- `system_linker_exec` is supported, i.e device is running on Android `>= 10`. +- Executable or interpreter path is under [`TERMUX_APP__DATA_DIR`] or [`TERMUX_APP__LEGACY_DATA_DIR`] directory. +This can be used if running in an untrusted app with `targetSdkVersion` `<= 28`. + +The executable or interpreter paths are checked under [`TERMUX_APP__DATA_DIR`]/[`TERMUX_APP__LEGACY_DATA_DIR`] instead of `TERMUX__ROOTFS` as files could be executed from `TERMUX__APPS_DIR` and `TERMUX__CACHE_DIR`, which are not under the Termux rootfs. Additionally, Termux rootfs may not exist under app data directory at all and could be under another directory under Android rootfs `/`, like if compiling packages for `shell` user for the `com.android.shell` package with the Termux rootfs under `/data/local/tmp` instead of `/data/data/com.android.shell` (and using `force` mode) or compiling packages for `/system` directory. + +##   + +  + + + +### TERMUX_EXEC__TESTS__LOG_LEVEL + +The log level for `termux-exec-tests`. + +**Type:** `int` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Default value:** `1` + +**Supported values:** + +- `0` (`OFF`) - Log nothing. + +- `1` (`NORMAL`) - Log error, warn and info messages and stacktraces. + +- `2` (`DEBUG`) - Log debug messages. + +- `3` (`VERBOSE`) - Log verbose messages. + +- `4` (`VVERBOSE`) - Log very verbose messages. + +- `5` (`VVVERBOSE`) - Log very very verbose messages. + +--- + +  + + + + + +## Output Environment Variables + +The `termux-exec` sets the following environment variables if required. + +- [`TERMUX_EXEC__PROC_SELF_EXE`](#termux_exec__proc_self_exe) + +  + + + +### TERMUX_EXEC__PROC_SELF_EXE + +If `system_linker_exec` is being used, then to execute the `/path/to/executable` file, we will be executing `/system/bin/linker64 /path/to/executable [args]`. + + The `/proc/pid/exe` file is a symbolic link containing the actual path of the executable being executed. However, if using `system_linker_exec`, then `/proc/pid/exe` will contain `/system/bin/linker64` instead of `/path/to/executable`. + +So `termux-exec` sets the `TERMUX_EXEC__PROC_SELF_EXE` env variable when `execve` is intercepted to the processed (normalized, absolutized and prefixed) path for the executable file that is to be executed with the linker. This allows patching software that reads `/proc/self/exe` in `termux-packages` build infrastructure to instead use `getenv("TERMUX_EXEC__PROC_SELF_EXE")`. + +  + +Note that if `termux-exec` is set in `LD_PRELOAD`, and it sets `TERMUX_EXEC__PROC_SELF_EXE` for the current process/shell, and then `LD_PRELOAD` is unset, then new processes after second nested `exec()` will get old and wrong value of `TERMUX_EXEC__PROC_SELF_EXE` belonging to the first nested process since `termux-exec` will not get called for the second nested process to set the updated value. The `termux-exec` will be called for the first nested process, because just unsetting `LD_PRELOAD` in current process will not unload the `termux-exec` library and it requires at least one nested `exec()`. The `termux-exec` library could unset `TERMUX_EXEC__PROC_SELF_EXE` if `LD_PRELOAD` isn't already set, but then if the first nested process is under [`TERMUX_APP__DATA_DIR`]/[`TERMUX_APP__LEGACY_DATA_DIR`], it will not have access to `TERMUX_EXEC__PROC_SELF_EXE` to read the actual value of the execution command. This would normally not be an issue if `LD_PRELOAD` being set to the `termux-exec` library is mandatory so that it can `system_linker_exec` commands if running with `targetSdkVersion` `>= 29` on an android `>= 10` device, as otherwise permission denied errors would trigger for any command under [`TERMUX_APP__DATA_DIR`]/[`TERMUX_APP__LEGACY_DATA_DIR`] anyways, unless user manually wraps second nested process with `/system/bin/linker64`. This will still be an issue if `system_linker_exec` is optional due to running with an older `targetSdkVersion` or on an older android device and `TERMUX_EXEC__SYSTEM_LINKER_EXEC` is set to `force`, since then `TERMUX_EXEC__PROC_SELF_EXE` would get exported and will be used by termux packages. + +**To prevent issues, if `LD_PRELOAD` is unset in current process, then `TERMUX_EXEC__PROC_SELF_EXE` must also be unset in the first nested process by the user themselves.** For example, running following will echo `/bin/sh` value twice instead of `/bin/sh` first and `/bin/dash` second if `LD_PRELOAD` were to be set. + +- `system_linker_exec` optional: `LD_PRELOAD= $TERMUX__PREFIX/bin/sh -c 'echo $TERMUX_EXEC__PROC_SELF_EXE'; $TERMUX__PREFIX/bin/dash -c "echo \$TERMUX_EXEC__PROC_SELF_EXE"'` +- `system_linker_exec` mandatory: `LD_PRELOAD= $TERMUX__PREFIX/bin/sh -c 'echo $TERMUX_EXEC__PROC_SELF_EXE'; /system/bin/linker64 $TERMUX__PREFIX/bin/dash -c "echo \$TERMUX_EXEC__PROC_SELF_EXE"'` + +**See Also:** + +- https://man7.org/linux/man-pages/man5/procfs.5.html + +**Type:** `string` + +**Commits:** [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 2.0.0`](https://github.com/termux/termux-exec/releases/tag/v2.0.0) + +**Assigned values:** + +- The normalized, absolutized and prefixed path to the executable file is being executed by `execve()` if `system_linker_exec` is being used. + +--- + +  + + + + + +## Processed Environment Variables + +The `termux-exec` processes the following environment variables if required. + +- [`LD_LIBRARY_PATH`](#ld_library_path) +- [`LD_PRELOAD`](#ld_preload) + +  + + + +### LD_LIBRARY_PATH + +The list of directory paths separated with colons `:` that should be searched in for dynamic shared libraries to link programs against. + +**See Also:** + +- https://manpages.debian.org/testing/manpages/ld.so.8.en.html#LD_LIBRARY_PATH + +**Type:** `string` + +**Commits:** [`13831552`](https://github.com/termux/termux-exec/commit/13831552), [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 0.9`](https://github.com/termux/termux-exec/releases/tag/v0.9) + +**Processing:** + +- If `execve` is intercepted, then `LD_LIBRARY_PATH` will be unset if executing a non native ELF file (like 32-bit binary on a 64-bit host) and executable path starts with `/system/`, but does not equal `/system/bin/sh`, `system/bin/linker` or `/system/bin/linker64`. + +##   + +  + + + +### LD_PRELOAD + +The list of ELF shared object paths separated with colons ":" to be loaded before all others. This feature can be used to selectively override functions in other shared objects. + +**See Also:** + +- https://manpages.debian.org/testing/manpages/ld.so.8.en.html#LD_PRELOAD + +**Type:** `string` + +**Commits:** [`13831552`](https://github.com/termux/termux-exec/commit/13831552), [`0281129f`](https://github.com/termux/termux-exec/commit/0281129f) + +**Version:** [`>= 0.9`](https://github.com/termux/termux-exec/releases/tag/v0.9) + +**Processing:** + +- If `execve` is intercepted, then `LD_PRELOAD` will be unset if executing a non native ELF file (like 32-bit binary on a 64-bit host) and executable path starts with `/system/`, but does not equal `/system/bin/sh`, `system/bin/linker` or `/system/bin/linker64`. + +##   + +  + +--- + +  + + + + + +[`properties.sh`]: https://github.com/termux/termux-packages/blob/master/scripts/properties.sh +[`TERMUX_APP__DATA_DIR`]: #termux_app__data_dir +[`TERMUX_APP__LEGACY_DATA_DIR`]: #termux_app__legacy_data_dir diff --git a/site/pages/en/projects/index.md b/site/pages/en/projects/index.md new file mode 100644 index 0000000..eef2146 --- /dev/null +++ b/site/pages/en/projects/index.md @@ -0,0 +1,45 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/index.html" +ark__replacement_strings: +- target: "docs/index.md" + replacement: "@ARK_PAGE__URL@/../docs/latest/index.html" +- target: "docs/developer/contribute/index.md" + replacement: "@ARK_PAGE__URL@/../docs/latest/developer/contribute/index.html" +--- + +# termux-exec-package + +The [`termux-exec`](https://github.com/termux/termux-exec) package provides a shared library that is meant to be preloaded with [`LD_PRELOAD`](https://man7.org/linux/man-pages/man8/ld.so.8.html) for proper functioning of the Termux execution environment. + +### Contents + +- [Releases](#releases) +- [Docs](#docs) + +--- + +  + + + + + +## Releases + +Check `releases` [here](releases/index.md). + +--- + +  + + + + + +## Docs + +Check `docs` [here](docs/index.md). If you intend to contribute to this repository, then also check `contribute` docs [here](docs/developer/contribute/index.md). + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.1.md b/site/pages/en/projects/releases/0/v0.1.md new file mode 100644 index 0000000..6287c22 --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.1.md @@ -0,0 +1,19 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.1.html" +--- + +# termux-exec-package v0.1 - 2017-09-17 + +## Changelog + +**Commit history:** [`v0.1`](https://github.com/termux/termux-exec/releases/tag/v0.1) + +  + + + +Initial release. + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.2.md b/site/pages/en/projects/releases/0/v0.2.md new file mode 100644 index 0000000..b17e0f8 --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.2.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.2.html" +--- + +# termux-exec-package v0.2 - 2017-09-17 + +## Changelog + +**Commit history:** [`v0.1...v0.2`](https://github.com/termux/termux-exec/compare/v0.1...v0.2) + +  + + + +### Fixed + +- Fixes argument being lost. ([`48f9e3ab`](https://github.com/termux/termux-exec/commit/48f9e3ab)) + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.3.md b/site/pages/en/projects/releases/0/v0.3.md new file mode 100644 index 0000000..34a9f4c --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.3.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.3.html" +--- + +# termux-exec-package v0.3 - 2017-10-01 + +## Changelog + +**Commit history:** [`v0.2...v0.3`](https://github.com/termux/termux-exec/compare/v0.2...v0.3) + +  + + + +### Fixed + +- Check the executable permission of files. Closes [#5](https://github.com/termux/termux-exec/issues/5). ([`e127449a`](https://github.com/termux/termux-exec/commit/e127449a)) + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.4.md b/site/pages/en/projects/releases/0/v0.4.md new file mode 100644 index 0000000..1d0f5d7 --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.4.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.4.html" +--- + +# termux-exec-package v0.4 - 2019-05-10 + +## Changelog + +**Commit history:** [`v0.3...v0.4`](https://github.com/termux/termux-exec/compare/v0.3...v0.4) + +  + + + +### Fixed + +- Respect `LDFLAGS` in `Makefile`. ([`d0ab1427`](https://github.com/termux/termux-exec/commit/d0ab1427)) + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.5.md b/site/pages/en/projects/releases/0/v0.5.md new file mode 100644 index 0000000..6f1890c --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.5.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.5.html" +--- + +# termux-exec-package v0.5 - 2020-02-21 + +## Changelog + +**Commit history:** [`v0.4...v0.5`](https://github.com/termux/termux-exec/compare/v0.4...v0.5) + +  + + + +### Added + +- Start android 10 proot wrapping experiment. ([`1720bb25`](https://github.com/termux/termux-exec/commit/1720bb25)) + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.6.md b/site/pages/en/projects/releases/0/v0.6.md new file mode 100644 index 0000000..cb88d93 --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.6.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.6.html" +--- + +# termux-exec-package v0.6 - 2020-10-31 + +## Changelog + +**Commit history:** [`v0.5...v0.6`](https://github.com/termux/termux-exec/compare/v0.5...v0.6) + +  + + + +### Fixed + +- Don't hardcode `/data/data/com.termux/*`. ([`7736a840`](https://github.com/termux/termux-exec/commit/7736a840)) + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.7.md b/site/pages/en/projects/releases/0/v0.7.md new file mode 100644 index 0000000..ccc1ece --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.7.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.7.html" +--- + +# termux-exec-package v0.7 - 2020-10-31 + +## Changelog + +**Commit history:** [`v0.6...v0.7`](https://github.com/termux/termux-exec/compare/v0.6...v0.7) + +  + + + +### Changed + +- Specify `DTERMUX_BASE_DIR` and `TERMUX_PREFIX` from `Makefile`. ([`4ca2778`](https://github.com/termux/termux-exec/commit/4ca2778)) + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.8.md b/site/pages/en/projects/releases/0/v0.8.md new file mode 100644 index 0000000..2c1b299 --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.8.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.8.html" +--- + +# termux-exec-package v0.8 - 2020-10-31 + +## Changelog + +**Commit history:** [`v0.7...v0.8`](https://github.com/termux/termux-exec/compare/v0.7...v0.8) + +  + + + +### Fixed + +- Use the correct buffer offsets. ([`6b3499ea`](https://github.com/termux/termux-exec/commit/6b3499ea)) + +--- + +  diff --git a/site/pages/en/projects/releases/0/v0.9.md b/site/pages/en/projects/releases/0/v0.9.md new file mode 100644 index 0000000..d83c3f7 --- /dev/null +++ b/site/pages/en/projects/releases/0/v0.9.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/0/v0.9.html" +--- + +# termux-exec-package v0.9 - 2021-02-09 + +## Changelog + +**Commit history:** [`v0.5...v0.9`](https://github.com/termux/termux-exec/compare/v0.5...v0.9) + +  + + + +### Fixed + +- Automatically unset `LD_PRELOAD` for `/system/bin` programs and when architecture does not match. Implemented by @easyaspi314 in [#17](https://github.com/termux/termux-exec/pull/17). ([`13831552`](https://github.com/termux/termux-exec/commit/13831552), [`2e71dbd8`](https://github.com/termux/termux-exec/commit/2e71dbd8)) + +--- + +  diff --git a/site/pages/en/projects/releases/1/v1.0.md b/site/pages/en/projects/releases/1/v1.0.md new file mode 100644 index 0000000..e3a9242 --- /dev/null +++ b/site/pages/en/projects/releases/1/v1.0.md @@ -0,0 +1,21 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/1/v1.0.html" +--- + +# termux-exec-package v1.0 - 2021-05-15 + +## Changelog + +**Commit history:** [`v0.9...v1.0`](https://github.com/termux/termux-exec/compare/v0.9...v1.0) + +  + + + +### Fixed + +- Update `Makefile` to respect `DESTDIR`. ([`b33392b5`](https://github.com/termux/termux-exec/commit/b33392b5)) + +--- + +  diff --git a/site/pages/en/projects/releases/index.md b/site/pages/en/projects/releases/index.md new file mode 100644 index 0000000..13cd878 --- /dev/null +++ b/site/pages/en/projects/releases/index.md @@ -0,0 +1,55 @@ +--- +page_ref: "@ARK_PROJECT__VARIANT@/termux/termux-exec-package/releases/index.html" +--- + +# termux-exec-package Releases + +This page lists the releases info for [`termux-exec`](https://github.com/termux/termux-exec). + +**The currently latest release of `termux-exec` is [`v1.0`](1/v1.0.md).** + +--- + +  + + + + + +## Release Sources + +The `termux-exec` is released on the following sources. + +- [GitHub releases](https://github.com/termux/termux-exec/releases). + +--- + +  + + + + + +## Release Versions + +Open a release to view its release notes and/or changelogs. Changelogs are generated as per the [Keep a Changelog](https://github.com/olivierlacan/keep-a-changelog) spec. + +### `v0` + +- [`v0.1`](0/v0.1.md) +- [`v0.2`](0/v0.2.md) +- [`v0.3`](0/v0.3.md) +- [`v0.4`](0/v0.4.md) +- [`v0.5`](0/v0.5.md) +- [`v0.6`](0/v0.6.md) +- [`v0.7`](0/v0.7.md) +- [`v0.8`](0/v0.8.md) +- [`v0.9`](0/v0.9.md) + +### `v1` + +- [`v1.0`](1/v1.0.md) + +--- + +