Skip to content

Commit 2dd3f4f

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

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

+800
-2453
lines changed

.github/workflows/docker_build.yml

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,79 @@ env:
1313
CI: true
1414
DOCKER_BUILDKIT: 1
1515

16+
# The GitHub ARM runner is capable of running
17+
# $PREFIX/bin/apt-get upgrade from within the Dockerfile
18+
# natively during the update process for both aarch64
19+
# and arm, demonstrating that it is compatible with
20+
# 32-bit binaries and capable of completely
21+
# replacing QEMU, but using it in the same workflow
22+
# as the x86 runner appears to require two separate jobs.
1623
jobs:
17-
main:
18-
runs-on: ubuntu-latest
24+
ARM:
25+
runs-on: ubuntu-24.04-arm
1926
strategy:
2027
matrix:
21-
CPU_ARCH:
28+
ARCHITECTURE:
2229
- aarch64
2330
- arm
24-
- i686
25-
- x86_64
2631
steps:
2732

2833
- name: Clone repository
2934
uses: actions/checkout@v4
3035

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
36+
- name: Set architecture variable
37+
run: echo "ARCHITECTURE=${{ matrix.ARCHITECTURE }}" >> $GITHUB_ENV
38+
39+
- name: Build image
40+
run: ./generate.sh
41+
42+
- name: Login to Docker Hub
43+
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
44+
uses: docker/login-action@v3
45+
with:
46+
username: grimler
47+
password: ${{ secrets.GRIMLER_DOCKER_TOKEN }}
48+
49+
- name: Push to Docker Hub
50+
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
51+
run: docker push termux/termux-docker:${{ env.ARCHITECTURE }}
3452

35-
- name: Build images
53+
- name: Export container as tar archive
54+
if: always()
3655
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-
.
56+
docker run \
57+
--name termux-docker-${{ env.ARCHITECTURE }} \
58+
termux/termux-docker:${{ env.ARCHITECTURE }} \
59+
uname -a
60+
docker stop termux-docker-${{ env.ARCHITECTURE }}
61+
docker export -o termux-docker-${{ env.ARCHITECTURE }}.tar \
62+
termux-docker-${{ env.ARCHITECTURE }}
63+
sha256sum termux-docker-${{ env.ARCHITECTURE }}.tar
64+
65+
- name: Store tar archive
66+
if: always()
67+
uses: actions/upload-artifact@v4
68+
with:
69+
name: termux-docker-${{ env.ARCHITECTURE }}-${{ github.sha }}
70+
path: termux-docker-${{ env.ARCHITECTURE }}.tar
71+
72+
x86:
73+
runs-on: ubuntu-latest
74+
strategy:
75+
matrix:
76+
ARCHITECTURE:
77+
- x86_64
78+
- i686
79+
steps:
80+
81+
- name: Clone repository
82+
uses: actions/checkout@v4
83+
84+
- name: Set architecture variable
85+
run: echo "ARCHITECTURE=${{ matrix.ARCHITECTURE }}" >> $GITHUB_ENV
86+
87+
- name: Build image
88+
run: ./generate.sh
4989

5090
- name: Login to Docker Hub
5191
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
@@ -57,28 +97,26 @@ jobs:
5797
- name: Push to Docker Hub
5898
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
5999
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
100+
docker push termux/termux-docker:${{ env.ARCHITECTURE }}
101+
if [ ${{ env.ARCHITECTURE }} = x86_64 ]; then
63102
docker push termux/termux-docker:latest
64103
fi
65104
66105
- name: Export container as tar archive
67106
if: always()
68107
run: |
69108
docker run \
70-
--privileged \
71-
--name termux-docker-${{ matrix.CPU_ARCH }} \
72-
termux/termux-docker:${{ matrix.CPU_ARCH }} \
109+
--name termux-docker-${{ env.ARCHITECTURE }} \
110+
termux/termux-docker:${{ env.ARCHITECTURE }} \
73111
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
112+
docker stop termux-docker-${{ env.ARCHITECTURE }}
113+
docker export -o termux-docker-${{ env.ARCHITECTURE }}.tar \
114+
termux-docker-${{ env.ARCHITECTURE }}
115+
sha256sum termux-docker-${{ env.ARCHITECTURE }}.tar
78116
79117
- name: Store tar archive
80118
if: always()
81119
uses: actions/upload-artifact@v4
82120
with:
83-
name: termux-docker-${{ matrix.CPU_ARCH }}-${{ github.sha }}
84-
path: termux-docker-${{ matrix.CPU_ARCH }}.tar
121+
name: termux-docker-${{ env.ARCHITECTURE }}-${{ github.sha }}
122+
path: termux-docker-${{ env.ARCHITECTURE }}.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 ROOTFS
6+
ARG TERMUX_APP_PACKAGE
7+
ARG TERMUX_PREFIX
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 be owned by the system user (1000:1000).
18+
COPY --chown=1000:1000 ${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 'pkg update' >> /update.sh && \
34+
echo 'apt-get 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 /data/data/${TERMUX_APP_PACKAGE}/cache/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_BASE_DIR
47+
ARG TERMUX_PREFIX
48+
49+
ENV ANDROID_DATA=/data
50+
ENV ANDROID_ROOT=/system
51+
ENV HOME=${TERMUX_BASE_DIR}/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_BASE_DIR}/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: 30 additions & 8 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
@@ -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
52+
Note that AArch64 and ARM containers sometimes work properly only in privileged
5353
mode. If you want your containers to have standard privileges, a custom
54-
seccomp profile is required.
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

0 commit comments

Comments
 (0)