forked from termux/termux-exec
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added: Add site, docs and old changelog files under
MIT
license
Related commit 24f60904
- Loading branch information
1 parent
5b5a1c7
commit 9d534ca
Showing
23 changed files
with
1,257 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <args> | ||
``` | ||
|
||
where the script has a `#!/path/to/interpreter` shebang, is replaced with: | ||
## Project | ||
|
||
```sh | ||
/system/bin/linker64 /path/to/interpreter ./path/to/myscript.sh <args> | ||
``` | ||
**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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
||
<!-- @ARK_DOCS__HEADER_PLACEHOLDER@ --> | ||
|
||
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 <branch_name>) | ||
|
||
# (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 <branch_name> | ||
|
||
# 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 `_<version>_<arch>.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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
||
<!-- @ARK_DOCS__HEADER_PLACEHOLDER@ --> | ||
|
||
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. | ||
|
||
``` | ||
<type>[optional scope]: <description> | ||
[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. | ||
|
||
--- | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
||
<!-- @ARK_DOCS__HEADER_PLACEHOLDER@ --> | ||
|
||
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) | ||
|
||
--- | ||
|
||
|
Oops, something went wrong.