Skip to content

Commit 320765e

Browse files
committed
deblobbify, replacing the system folder with several other components
1 parent e3c861f commit 320765e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+767
-2459
lines changed

.github/workflows/docker_build.yml

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,29 @@ env:
1414
DOCKER_BUILDKIT: 1
1515

1616
jobs:
17-
main:
18-
runs-on: ubuntu-latest
17+
generate:
1918
strategy:
2019
matrix:
21-
CPU_ARCH:
22-
- aarch64
23-
- arm
24-
- i686
25-
- x86_64
20+
include:
21+
- runner: ubuntu-24.04
22+
architecture: i686
23+
- runner: ubuntu-24.04
24+
architecture: x86_64
25+
- runner: ubuntu-24.04-arm
26+
architecture: arm
27+
- runner: ubuntu-24.04-arm
28+
architecture: aarch64
29+
runs-on: ${{ matrix.runner }}
2630
steps:
2731

32+
- name: Set architecture variable
33+
run: echo "TERMUX_ARCH=${{ matrix.architecture }}" >> $GITHUB_ENV
34+
2835
- name: Clone repository
2936
uses: actions/checkout@v4
3037

31-
- name: Setup binfmt_misc
32-
if: (matrix.CPU_ARCH == 'aarch64') || (matrix.CPU_ARCH == 'arm')
33-
run: docker run --rm --privileged aptman/qus -s -- -p aarch64 arm
34-
35-
- name: Build images
36-
run: |
37-
case '${{ matrix.CPU_ARCH }}' in
38-
arm) SYSTEM_TYPE=arm; PLATFORM_TAG="linux/arm/v7";;
39-
aarch64) SYSTEM_TYPE=arm; PLATFORM_TAG="linux/arm64";;
40-
i686) SYSTEM_TYPE=x86; PLATFORM_TAG="linux/386";;
41-
*) SYSTEM_TYPE=x86; PLATFORM_TAG="linux/amd64";;
42-
esac
43-
docker buildx build -t \
44-
termux/termux-docker:${{ matrix.CPU_ARCH }} \
45-
--platform "$PLATFORM_TAG" \
46-
--build-arg BOOTSTRAP_ARCH=${{ matrix.CPU_ARCH }} \
47-
--build-arg SYSTEM_TYPE="${SYSTEM_TYPE}" \
48-
.
38+
- name: Build image
39+
run: ./generate.sh
4940

5041
- name: Login to Docker Hub
5142
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
@@ -57,28 +48,26 @@ jobs:
5748
- name: Push to Docker Hub
5849
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
5950
run: |
60-
docker push termux/termux-docker:${{ matrix.CPU_ARCH }}
61-
if [ ${{ matrix.CPU_ARCH }} = i686 ]; then
62-
docker tag termux/termux-docker:i686 termux/termux-docker:latest
51+
docker push termux/termux-docker:${{ env.TERMUX_ARCH }}
52+
if [ ${{ env.TERMUX_ARCH }} = x86_64 ]; then
6353
docker push termux/termux-docker:latest
6454
fi
6555
6656
- name: Export container as tar archive
6757
if: always()
6858
run: |
6959
docker run \
70-
--privileged \
71-
--name termux-docker-${{ matrix.CPU_ARCH }} \
72-
termux/termux-docker:${{ matrix.CPU_ARCH }} \
60+
--name termux-docker-${{ env.TERMUX_ARCH }} \
61+
termux/termux-docker:${{ env.TERMUX_ARCH }} \
7362
uname -a
74-
docker stop termux-docker-${{ matrix.CPU_ARCH }}
75-
docker export -o termux-docker-${{ matrix.CPU_ARCH }}.tar \
76-
termux-docker-${{ matrix.CPU_ARCH }}
77-
sha256sum termux-docker-${{ matrix.CPU_ARCH }}.tar
63+
docker stop termux-docker-${{ env.TERMUX_ARCH }}
64+
docker export -o termux-docker-${{ env.TERMUX_ARCH }}.tar \
65+
termux-docker-${{ env.TERMUX_ARCH }}
66+
sha256sum termux-docker-${{ env.TERMUX_ARCH }}.tar
7867
7968
- name: Store tar archive
8069
if: always()
8170
uses: actions/upload-artifact@v4
8271
with:
83-
name: termux-docker-${{ matrix.CPU_ARCH }}-${{ github.sha }}
84-
path: termux-docker-${{ matrix.CPU_ARCH }}.tar
72+
name: termux-docker-${{ env.TERMUX_ARCH }}-${{ github.sha }}
73+
path: termux-docker-${{ env.TERMUX_ARCH }}.tar

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
termux-docker-rootfs

Dockerfile

Lines changed: 48 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2,90 +2,64 @@
22
# Bootstrap Termux environment.
33
FROM scratch AS bootstrap
44

5-
ARG BOOTSTRAP_VERSION=2023.02.19-r1%2Bapt-android-7
6-
ARG BOOTSTRAP_ARCH=i686
7-
ARG SYSTEM_TYPE=x86
5+
ARG TERMUX_DOCKER__ROOTFS
6+
ARG TERMUX__PREFIX
7+
ARG TERMUX__CACHE_DIR
88

9-
# Docker uses /bin/sh by default, but we don't have it currently.
10-
SHELL ["/system/bin/sh", "-c"]
11-
ENV PATH /system/bin
9+
# Install generated rootfs containing:
10+
# - termux bootstrap
11+
# - aosp-libs (bionic libc, linker, boringssl, zlib, libicuuc, debuggerd)
12+
# - aosp-utils (toybox, mksh, iputils)
13+
# - libandroid-stub
14+
# - dnsmasq
15+
# Since /system is now a symbolic link to $PREFIX/opt/aosp,
16+
# which has contents that can be updated by the system user via apt,
17+
# the entire rootfs is now owned by the system user (1000:1000).
18+
COPY --chown=1000:1000 ${TERMUX_DOCKER__ROOTFS} /
1219

13-
# Copy libc, linker and few utilities.
14-
COPY /system/$SYSTEM_TYPE /system
20+
# Docker uses /bin/sh by default, but we don't have it.
21+
ENV PATH=/system/bin
22+
SHELL ["sh", "-c"]
1523

16-
# Copy entrypoint script.
17-
COPY /entrypoint.sh /entrypoint.sh
18-
COPY /entrypoint_root.sh /entrypoint_root.sh
19-
20-
# Extract bootstrap archive and create symlinks.
21-
ADD https://github.com/termux/termux-packages/releases/download/bootstrap-$BOOTSTRAP_VERSION/bootstrap-$BOOTSTRAP_ARCH.zip /bootstrap.zip
22-
RUN busybox mkdir -p /data/data/com.termux/files && \
23-
cd /data/data/com.termux/files && \
24-
busybox mkdir ../cache ./usr ./home && \
25-
busybox unzip -d usr /bootstrap.zip && \
26-
busybox rm /bootstrap.zip && \
27-
cd ./usr && \
28-
busybox cat SYMLINKS.txt | while read -r line; do \
29-
dest=$(echo "$line" | busybox awk -F '←' '{ print $1 }'); \
30-
link=$(echo "$line" | busybox awk -F '←' '{ print $2 }'); \
31-
busybox ln -s "$dest" "$link"; \
32-
done && \
33-
busybox rm SYMLINKS.txt && \
34-
busybox ln -s /data/data/com.termux/files/usr /usr && \
35-
busybox ln -s /data/data/com.termux/files/usr/bin /bin && \
36-
busybox ln -s /data/data/com.termux/files/usr/tmp /tmp
37-
38-
# Link some utilities to busybox.
39-
# Some utilities in $PREFIX are actually a wrapper of the same binary
40-
# from /system/bin. See termux-tools/build.sh#L29.
41-
RUN for tool in df mount ping ping6 su top umount; do \
42-
busybox ln -s /system/bin/busybox /system/bin/$tool; \
43-
done
44-
45-
# Set ownership and file access modes:
46-
# * User content is owned by 1000:1000.
47-
# * Termux file modes are set only for user.
48-
# * Rest is owned by root and has 755/644 modes.
49-
RUN busybox chown -Rh 0:0 /system && \
50-
busybox chown -Rh 1000:1000 /data/data/com.termux && \
51-
busybox ln -s /system/etc/passwd /etc/passwd && \
52-
busybox ln -s /system/etc/group /etc/group && \
53-
busybox find /system -type d -exec busybox chmod 755 "{}" \; && \
54-
busybox find /system -type f -executable -exec busybox chmod 755 "{}" \; && \
55-
busybox find /system -type f ! -executable -exec busybox chmod 644 "{}" \; && \
56-
busybox find /data -type d -exec busybox chmod 755 "{}" \; && \
57-
busybox find /data/data/com.termux/files -type f -o -type d -exec busybox chmod g-rwx,o-rwx "{}" \; && \
58-
cd /data/data/com.termux/files/usr && \
59-
busybox find ./bin ./lib/apt ./libexec -type f -exec busybox chmod 700 "{}" \;
60-
61-
# Install updates and cleanup when not building for arm.
62-
ENV PATH /data/data/com.termux/files/usr/bin
63-
RUN if [ ${SYSTEM_TYPE} = 'arm' ]; then exit; else \
64-
/system/bin/mksh -T /dev/ptmx -c "/system/bin/dnsmasq -u root -g root --pid-file /dnsmasq.pid" && sleep 1 && \
65-
su - system -c "/data/data/com.termux/files/usr/bin/apt update" && \
66-
su - system -c "/data/data/com.termux/files/usr/bin/apt upgrade -o Dpkg::Options::=--force-confnew -yq" && \
67-
rm -rf /data/data/com.termux/files/usr/var/lib/apt/* && \
68-
rm -rf /data/data/com.termux/files/usr/var/log/apt/* && \
69-
rm -rf /data/data/com.termux/cache/apt/* ;\
70-
fi
24+
# Install updates and cleanup
25+
# Start dnsmasq to resolve hostnames, and,
26+
# for some reason the -c argument of toybox-su is not working,
27+
# so this odd-looking script forces the update process
28+
# to work using the -s argument of toybox-su instead, which is working.
29+
RUN sh -T /dev/ptmx -c "$TERMUX__PREFIX/bin/dnsmasq -u root -g root --pid-file=/dnsmasq.pid" && \
30+
sleep 1 && \
31+
echo '#!/system/bin/sh' > /update.sh && \
32+
echo "PATH=$TERMUX__PREFIX/bin" >> /update.sh && \
33+
echo 'apt update' >> /update.sh && \
34+
echo 'apt upgrade -o Dpkg::Options::=--force-confnew -y' >> /update.sh && \
35+
chmod +x /update.sh && \
36+
su system -s /update.sh && \
37+
rm -f /update.sh && \
38+
rm -rf "${TERMUX__PREFIX}"/var/lib/apt/* && \
39+
rm -rf "${TERMUX__PREFIX}"/var/log/apt/* && \
40+
rm -rf "${TERMUX__CACHE_DIR}"/apt/*
7141

7242
##############################################################################
7343
# Create final image.
7444
FROM scratch
7545

76-
ENV ANDROID_DATA /data
77-
ENV ANDROID_ROOT /system
78-
ENV HOME /data/data/com.termux/files/home
79-
ENV LANG en_US.UTF-8
80-
ENV PATH /data/data/com.termux/files/usr/bin
81-
ENV PREFIX /data/data/com.termux/files/usr
82-
ENV TMPDIR /data/data/com.termux/files/usr/tmp
83-
ENV TZ UTC
46+
ARG TERMUX__PREFIX
47+
ARG TERMUX__HOME
48+
49+
ENV ANDROID_DATA=/data
50+
ENV ANDROID_ROOT=/system
51+
ENV HOME=${TERMUX__HOME}
52+
ENV LANG=en_US.UTF-8
53+
ENV PATH=${TERMUX__PREFIX}/bin
54+
ENV PREFIX=${TERMUX__PREFIX}
55+
ENV TMPDIR=${TERMUX__PREFIX}/tmp
56+
ENV TZ=UTC
57+
ENV TERM=xterm
8458

8559
COPY --from=bootstrap / /
8660

87-
WORKDIR /data/data/com.termux/files/home
88-
SHELL ["/data/data/com.termux/files/usr/bin/sh", "-c"]
61+
WORKDIR ${TERMUX__HOME}
62+
SHELL ["sh", "-c"]
8963

9064
ENTRYPOINT ["/entrypoint.sh"]
91-
CMD ["/data/data/com.termux/files/usr/bin/login"]
65+
CMD ["login"]

README.md

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ normal Termux installation.
2121
docker run -it termux/termux-docker:latest
2222
```
2323

24-
When using the tag `latest`, container will be 32 bit (i686 architecture).
24+
When using the tag `latest`, container will be 64 bit (x86_64 architecture).
2525

2626
Other architecture can be installed using a different tags. Available
2727
tags:
2828

2929
- `aarch64`
3030
- `arm`
31-
- `i686` (`latest`)
32-
- `x86_64`
31+
- `i686`
32+
- `x86_64` (`latest`)
3333

3434
If architecture is not compatible with host, the additional setup will
3535
be needed. Read this document further to learn how you can run containers
@@ -39,7 +39,7 @@ of incompatible CPU architecture.
3939
The initial user of container must be root. Otherwise DNS will be broken
4040
because of `dnsmasq` server failure.
4141

42-
### Running ARM containers on x86 host
42+
### Running ARM containers
4343

4444
In order to run AArch64 container on x86(64) host, you need to setup
4545
QEMU emulator through binfmt_misc. This can be easily done by one
@@ -49,9 +49,12 @@ command:
4949
docker run --rm --privileged aptman/qus -s -- -p aarch64 arm
5050
```
5151

52-
Note that AArch64 and ARM containers work properly only in privileged
53-
mode. If you want your containers to have standard privileges, a custom
54-
seccomp profile is required.
52+
Note that AArch64 and ARM containers sometimes work properly only in privileged
53+
mode, even on some real ARM devices. If you want your containers to have standard privileges, a custom
54+
seccomp profile or a custom build of Docker might be required. The custom build
55+
of Docker limits the customizations to purely what is necessary for
56+
the `personality()` system call, leaving the security settings of all other system
57+
calls untouched.
5558

5659
Variant with privileged container:
5760

@@ -65,6 +68,25 @@ Variant with seccomp unconfined profile:
6568
docker run -it --security-opt seccomp:unconfined termux/termux-docker:aarch64
6669
```
6770

71+
Variant with custom build of Docker:
72+
73+
> [!NOTE]
74+
> Example with Debian bookworm `armhf` host and the `docker.io` package. Assumes that [`deb-src` URIs](https://wiki.debian.org/Packaging/SourcePackage?action=show&redirect=SourcePackage#With_apt-get_source) and the [`devscripts` package](https://wiki.debian.org/Packaging#Suggested_tools_to_create_an_environment_for_packaging) are already installed, and that the current user is a member of the `docker` group.
75+
76+
```.sh
77+
sudo apt build-dep docker.io
78+
apt source docker.io
79+
cp /path/to/termux-docker/custom-docker-with-unrestricted-personality.patch docker.io-*/debian/patches/
80+
echo 'custom-docker-with-unrestricted-personality.patch' >> docker.io-*/debian/patches/series
81+
cd docker.io-*/
82+
DEB_BUILD_OPTIONS=nocheck debuild -b -uc -us
83+
rm ../golang*
84+
sudo apt install ../*.deb
85+
docker run -it termux/termux-docker:arm
86+
```
87+
88+
You might then want to temporarily use `sudo apt-mark hold docker.io` to ensure the package is not automatically upgraded, causing termux-docker to stop working on the device in the future, but **not upgrading can be a security risk**. If using the patch, it is recommended to patch and recompile the Docker daemon after every upgrade.
89+
6890
### Non-interactive execution of commands
6991

7092
You can run commands in non-interactive mode. Just append them to Docker
@@ -99,20 +121,20 @@ docker run -it --entrypoint /entrypoint_root.sh termux/termux-docker:latest
99121
Docker:
100122

101123
```.sh
102-
./build-all.sh
124+
./generate.sh
103125
```
104126

105127
Podman:
106128

107129
```.sh
108-
./build-all.sh --podman
130+
./generate.sh --podman
109131
```
110132

111133
## Known issues
112134

113135
There a number of known issues which may not be resolved:
114136

115-
* ARM containers may require a custom seccomp profile to remove restrictions from
137+
* ARM containers might require a custom seccomp profile or custom build of Docker to remove restrictions from the
116138
`personality()` system call.
117139

118140
* When running certain multi threaded program in 32bit containers, the PIDs can

build-all.sh

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)