Termux Selected For NLnet NGI Mobifree Grant

Termux has been approved to receive a grant from the NLnet Foundation under its NGI Mobifree (1, 2) program for the June 2024 call. NGI Mobifree is a pilot within the European Commission's Next Generation Internet (NGI) initiative. The public announcement by NLnet is available at https://nlnet.nl/news/2024/20241111-NGI-Mobifree-grants.html with our project page at https://nlnet.nl/project/Termux.

Henrik Grimler and agnostic-apollo are really grateful for this opportunity and really excited to work with the NLnet Foundation under the grant.

Under the NGI Mobifree grant the following three improvements to Termux are planned to be implemented.

  1. termux-core Library
  2. APK Library File (APKLF)
  3. Dynamic Variables

 

termux-core Library

The termux-core library will be created which will allow external projects to use Termux execution environment and packages in their own apps. Currently, to integrate Termux in third party apps requires a full fork of Termux app and manual integration.

The library is planned to be provided under the MIT license to increase adoption and prevent license conflicts as we want termux-core to be more attractive to external projects and commercial entities that could have uses for a termux-ish environment in their app. We hope the MIT license + proof-of-concept demonstrations can help us land some support contracts, and make the Termux project more economically sustainable.


 

APK Library File (APKLF)

A new APK Library File (APKLF) execution/packaging design will be implemented so that Termux can comply with security restrictions added in Android 10 prevents apps from executing downloaded packages if an app uses targetSdkVersion >= 29 (Android 10). As a workaround Termux is currently using targetSdkVersion = 28 (Android 9) to run in backward compatibility mode.

Check the App Data File Execute Restrictions, including the untrusted_app* SeLinux Policy section for more info on the Android security restrictions. Check the termux/termux-app#1072: No more exec from data folder on targetAPI >= Android Q and termux/termux-app#2155: Revisit the Android W^X problem issues for discussions regarding the issues and possible solutions. To understand how Termux executes files, check the Termux Execution Environment docs.

Check the APK Native Library docs for more info on the APKLF design, and the Issues sections for details on all its issues that need to be solved. A proper design doc and info on additional issues will be published in near future.

APKLF design is very critical for long term functioning and stability of the Termux app, as the exemption allowed by Android for apps like Termux to execute downloaded files by using targetSdkVersion = 28 (Android 9) may end in some future Android version, which will break Termux completely. Android has already bumped PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION to 28 in Android 14 and there are plans to bump it to 29 soon, which will then show a message when Termux app is launched to warn the users that app may not work properly as its targeting too old an sdk. (1, 2) Additionally, this is required for temrux-core library as well as external apps, especially ones on Google PlayStore, cannot use older targetSdkVersion like Termux does to bypass restrictions.

Context

Android restricts execution based on SeLinux policies and contexts assigned to app processes (untrusted_app*) and their files under app data directory (app_data_file). If a file exists in the private app data directory /data/data/<package_name> of the app, in which files can be created at runtime, Android does not allow execution if app uses targetSdkVersion >= 29 as that is considered a security risk to allow random code to be executed. Google wants only files that exist inside app APKs to be executable as APKs can be scanned for malicious files, either on device or when uploaded to app stores like Google PlayStore. This is a different security model than how general purpose computers work which allow downloading and executing code without any restrictions.


 

Dynamic Variables

Termux package sources will be patched to read paths from environment variables exported by the app, or compiled package files will be patched at install time, rather than relying on hardcoded paths in the package files to Termux rootfs.

Termux packages currently use hardcoded paths/variables that are added/replaced in package sources at build time for its Termux rootfs directory /data/data/com.termux/files under the app data directory that Android is expected to assign to the Termux app if its installed in the primary Android user 0. This prevents Termux packages to run if Termux app is installed in secondary users/work profiles, or on external sdcards, or if packages are running in an external app with a different app data or rootfs directory, unless packages are compiled specifically for the different rootfs path.

There are currently around ~4000 placeholders in package source/patch files that are replaced at build time with Termux variables. There are also additional variables passed as build time config to package source builder scripts. To solve the issues of hardcoded values, following will be done.

Executable files will not use the placeholder-patch design at install time as for APKLF design, the executables will be read-only library files under the system owned APK native library directory (ApplicationInfo.nativeLibraryDir) /data/app/*<package_name>/lib/<arch>.

Packages that have been updated to dynamic variables design will be be marked as such in their package build build.sh files and deb control files. All the packages dependencies would need to be fixed as well before a package can be marked. Initially only the bootstrap and other important/popular packages will be patched.

Once packages are fixed to use environment variables, it should also allow external projects with a different app package name to execute packages already compiled for Termux app rootfs without having to recompile them from source, which often takes many hours and significant cpu/memory resources, so would ease adoption of Termux in external projects. However, packages may still have references to Termux name/urls inside them that are added at build time, and if an external project does not want that, then they will need to compile packages themselves anyways with their project specific values, but that will at least allow Termux packages to work if their app is installed on secondary users/work profiles, or on external sdcards.

Check the Termux Filesystem Layout docs for more info on the Termux filesystem and the Termux rootfs.