Browse Source

apt: prevent usage of certain commands as root

Usage of package manager as root has certain bad effects in Termux such as
messed up SELinux contexts and ownership. Root checks done in 'pkg' wrapper
are not reliable because one can execute 'apt' directly or with third-party
script downloaded from the Internet.

This commit adds user id check and if it found that uid is 0, apt will
refuse to do any work in root session. These checks done in such way so
they cannot be bypassed in any way unless command is executed as non-root
user.

Those who use Termux via ADB root shell should be able to switch to Termux
user id with command 'su' in order to have package manager working.

---

This change also affects the 'termux-info' utility:

 * It will no longer use 'apt policy' to detect subscribed repositories. Each
   source will be checked by script manually.

 * Information will be copied to clipboard only if 'termux-api' is installed.

 * Syntax error in timeout command is fixed: 'timeout' doesn't understand the
   argument '-t'.

 * Minor information entries reordering.
emacs-27
Leonid Plyushch 5 years ago
parent
commit
ecd613166b
No known key found for this signature in database GPG Key ID: 45F2964132545795
  1. 105
      packages/apt/0010-prevent-usage-as-root.patch
  2. 2
      packages/apt/build.sh
  3. 5
      packages/termux-tools/build.sh
  4. 17
      packages/termux-tools/pkg
  5. 57
      packages/termux-tools/termux-info

105
packages/apt/0010-prevent-usage-as-root.patch

@ -0,0 +1,105 @@
diff -uNr apt-1.4.9/cmdline/apt.cc apt-1.4.9.mod/cmdline/apt.cc
--- apt-1.4.9/cmdline/apt.cc 2019-01-18 12:42:07.000000000 +0200
+++ apt-1.4.9.mod/cmdline/apt.cc 2019-11-13 14:55:50.954692940 +0200
@@ -97,6 +97,12 @@
/*}}}*/
int main(int argc, const char *argv[]) /*{{{*/
{
+ if (getuid() == 0) {
+ std::cout << "You should not use command 'apt' as root." << std::endl;
+ std::cout << "This is dangerous as may damage your Termux installation and data." << std::endl;
+ return 1;
+ }
+
CommandLine CmdL;
auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT, &_config, &_system, argc, argv, &ShowHelp, &GetCommands);
diff -uNr apt-1.4.9/cmdline/apt-get.cc apt-1.4.9.mod/cmdline/apt-get.cc
--- apt-1.4.9/cmdline/apt-get.cc 2019-01-18 12:42:07.000000000 +0200
+++ apt-1.4.9.mod/cmdline/apt-get.cc 2019-11-13 14:55:50.954692940 +0200
@@ -432,6 +432,12 @@
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
+ if (getuid() == 0) {
+ std::cout << "You should not use command 'apt-get' as root." << std::endl;
+ std::cout << "This is dangerous as may damage your Termux installation and data." << std::endl;
+ return 1;
+ }
+
// Parse the command line and initialize the package library
CommandLine CmdL;
auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT_GET, &_config, &_system, argc, argv, &ShowHelp, &GetCommands);
diff -uNr apt-1.4.9/cmdline/apt-key.in apt-1.4.9.mod/cmdline/apt-key.in
--- apt-1.4.9/cmdline/apt-key.in 2019-11-13 14:55:25.431240010 +0200
+++ apt-1.4.9.mod/cmdline/apt-key.in 2019-11-13 15:04:25.853655116 +0200
@@ -15,8 +15,11 @@
aptkey_echo() { echo "$@"; }
-requires_root() {
- :
+assert_no_root() {
+ if [ "$(id -u)" = "0" ]; then
+ apt_error "Refusing to run 'apt-key' as root to prevent damage to your Termux installation."
+ exit 1
+ fi
}
command_available() {
@@ -510,7 +513,6 @@
create_new_keyring() { if [ ! -r "$FORCED_KEYRING" ]; then TRUSTEDFILE='/dev/null'; FORCED_KEYRING="$TRUSTEDFILE"; fi; }
;;
--fakeroot)
- requires_root() { true; }
;;
--quiet)
aptkey_echo() { true; }
@@ -706,7 +708,7 @@
case "$command" in
add)
warn_on_script_usage
- requires_root
+ assert_no_root
setup_merged_keyring
aptkey_execute "$GPG" --quiet --batch --import "$@"
merge_back_changes
@@ -714,19 +716,19 @@
;;
del|rm|remove)
# no script warning here as removing 'add' usage needs 'del' for cleanup
- requires_root
+ assert_no_root
foreach_keyring_do 'remove_key_from_keyring' "$@"
aptkey_echo "OK"
;;
update)
warn_on_script_usage
- requires_root
+ assert_no_root
setup_merged_keyring
update
merge_back_changes
;;
net-update)
- requires_root
+ assert_no_root
setup_merged_keyring
net_update
merge_back_changes
diff -uNr apt-1.4.9/cmdline/apt-mark.cc apt-1.4.9.mod/cmdline/apt-mark.cc
--- apt-1.4.9/cmdline/apt-mark.cc 2019-01-18 12:42:07.000000000 +0200
+++ apt-1.4.9.mod/cmdline/apt-mark.cc 2019-11-13 14:55:50.958026289 +0200
@@ -316,6 +316,12 @@
/*}}}*/
int main(int argc,const char *argv[]) /*{{{*/
{
+ if (getuid() == 0) {
+ std::cout << "You should not use command 'apt-mark' as root." << std::endl;
+ std::cout << "This is dangerous as may damage your Termux installation and data." << std::endl;
+ return 1;
+ }
+
CommandLine CmdL;
auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT_MARK, &_config, &_system, argc, argv, &ShowHelp, &GetCommands);

2
packages/apt/build.sh

@ -2,7 +2,7 @@ TERMUX_PKG_HOMEPAGE=https://packages.debian.org/apt
TERMUX_PKG_DESCRIPTION="Front-end for the dpkg package manager" TERMUX_PKG_DESCRIPTION="Front-end for the dpkg package manager"
TERMUX_PKG_LICENSE="GPL-2.0" TERMUX_PKG_LICENSE="GPL-2.0"
TERMUX_PKG_VERSION=1.4.9 TERMUX_PKG_VERSION=1.4.9
TERMUX_PKG_REVISION=20 TERMUX_PKG_REVISION=21
TERMUX_PKG_SRCURL=http://ftp.debian.org/debian/pool/main/a/apt/apt_${TERMUX_PKG_VERSION}.tar.xz TERMUX_PKG_SRCURL=http://ftp.debian.org/debian/pool/main/a/apt/apt_${TERMUX_PKG_VERSION}.tar.xz
TERMUX_PKG_SHA256=d4d65e7c84da86f3e6dcc933bba46a08db429c9d933b667c864f5c0e880bac0d TERMUX_PKG_SHA256=d4d65e7c84da86f3e6dcc933bba46a08db429c9d933b667c864f5c0e880bac0d
# apt-key requires utilities from coreutils, findutils, gpgv, grep, sed. # apt-key requires utilities from coreutils, findutils, gpgv, grep, sed.

5
packages/termux-tools/build.sh

@ -1,12 +1,13 @@
TERMUX_PKG_HOMEPAGE=https://termux.com/ TERMUX_PKG_HOMEPAGE=https://termux.com/
TERMUX_PKG_DESCRIPTION="Basic system tools for Termux" TERMUX_PKG_DESCRIPTION="Basic system tools for Termux"
TERMUX_PKG_LICENSE="GPL-3.0" TERMUX_PKG_LICENSE="GPL-3.0"
TERMUX_PKG_VERSION=0.73 TERMUX_PKG_VERSION=0.74
TERMUX_PKG_SKIP_SRC_EXTRACT=true TERMUX_PKG_SKIP_SRC_EXTRACT=true
TERMUX_PKG_PLATFORM_INDEPENDENT=true TERMUX_PKG_PLATFORM_INDEPENDENT=true
TERMUX_PKG_ESSENTIAL=true TERMUX_PKG_ESSENTIAL=true
TERMUX_PKG_CONFFILES="etc/motd"
TERMUX_PKG_CONFLICTS="procps (<< 3.3.15-2)" TERMUX_PKG_CONFLICTS="procps (<< 3.3.15-2)"
TERMUX_PKG_SUGGESTS="termux-api"
TERMUX_PKG_CONFFILES="etc/motd"
# Some of these packages are not dependencies and used only to ensure # Some of these packages are not dependencies and used only to ensure
# that core packages are installed after upgrading (we removed busybox # that core packages are installed after upgrading (we removed busybox

17
packages/termux-tools/pkg

@ -18,13 +18,6 @@ show_help() {
exit 1 exit 1
} }
assert_not_root() {
if [ $(id -u) -eq 0 ]; then
echo "This must NOT be run as root as it will break your environment (root will be required for nearly everything due to changed file permissions)"
exit 1
fi
}
check_pkgcache() { check_pkgcache() {
if [ -z "$(find @TERMUX_PREFIX@/var/cache/apt/pkgcache.bin -mmin -5)" ]; then if [ -z "$(find @TERMUX_PREFIX@/var/cache/apt/pkgcache.bin -mmin -5)" ]; then
apt update apt update
@ -41,13 +34,13 @@ shift 1
case "$CMD" in case "$CMD" in
f*) dpkg -L "$@";; f*) dpkg -L "$@";;
h*) show_help;; h*) show_help;;
add|i*) assert_not_root; check_pkgcache; apt install "$@";; add|i*) check_pkgcache; apt install "$@";;
list-a*) apt list "$@";; list-a*) apt list "$@";;
list-i*) apt list --installed "$@";; list-i*) apt list --installed "$@";;
rei*) assert_not_root; apt install --reinstall "$@";; rei*) apt install --reinstall "$@";;
se*) assert_not_root; check_pkgcache; apt search "$@";; se*) check_pkgcache; apt search "$@";;
sh*) apt show "$@";; sh*) apt show "$@";;
un*|rem*|rm|del*) assert_not_root; apt remove "$@";; un*|rem*|rm|del*) apt remove "$@";;
up*) assert_not_root; apt update; apt full-upgrade "$@";; up*) apt update; apt full-upgrade "$@";;
*) echo "Unknown command: '$CMD' (run 'pkg help' for usage information)"; exit 1;; *) echo "Unknown command: '$CMD' (run 'pkg help' for usage information)"; exit 1;;
esac esac

57
packages/termux-tools/termux-info

@ -1,5 +1,4 @@
#!/bin/sh #!/bin/bash
if [ "$#" != "0" ]; then if [ "$#" != "0" ]; then
echo 'usage: termux-info' echo 'usage: termux-info'
@ -8,32 +7,68 @@ if [ "$#" != "0" ]; then
fi fi
updates() { updates() {
local updatable
if [ "$(id -u)" = "0" ]; then
echo "Running as root. Cannot check package updates."
else
apt update >/dev/null 2>&1 apt update >/dev/null 2>&1
updatable=$(apt list --upgradable 2>/dev/null | tail -n +2) updatable=$(apt list --upgradable 2>/dev/null | tail -n +2)
if [ -z "$updatable" ];then if [ -z "$updatable" ];then
echo "All packages up to date" echo "All packages up to date"
else else
echo "$updatable" echo "$updatable"
fi fi
fi
} }
output="Updatable packages: repo_subscriptions() {
$(updates) local main_sources
Subscribed repositories: main_sources=$(grep -P '^\s*deb\s' "@TERMUX_PREFIX@/etc/apt/sources.list")
$(apt-cache policy | grep http | awk '{print $2 " " $3}')
System information: if [ -n "$main_sources" ]; then
$(uname -a) echo "# sources.list"
Termux-packages arch: echo "$main_sources"
fi
local filename repo_package supl_sources
while read -r filename; do
repo_package=$(dpkg -S "$filename" 2>/dev/null | cut -d : -f 1)
supl_sources=$(grep -P '^\s*deb\s' "$filename")
if [ -n "$supl_sources" ]; then
if [ -n "$repo_package" ]; then
echo "# $repo_package (sources.list.d/$(basename "$filename"))"
else
echo "# sources.list.d/$(basename "$filename")"
fi
echo "$supl_sources"
fi
done < <(find "@TERMUX_PREFIX@/etc/apt/sources.list.d" -maxdepth 1 ! -type d)
}
output="Packages CPU architecture:
$(dpkg --print-architecture) $(dpkg --print-architecture)
Subscribed repositories:
$(repo_subscriptions)
Updatable packages:
$(updates)
Android version: Android version:
$(getprop ro.build.version.release) $(getprop ro.build.version.release)
Kernel build information:
$(uname -a)
Device manufacturer: Device manufacturer:
$(getprop ro.product.manufacturer) $(getprop ro.product.manufacturer)
Device model: Device model:
$(getprop ro.product.model)" $(getprop ro.product.model)"
echo "$output" echo "$output"
if [ -n "$(command -v termux-clipboard-set)" ]; then
# Copy to clipboard (requires termux-api) # Copy to clipboard (requires termux-api)
# use timeout in case termux-api is installed but the termux:api app is missing # use timeout in case termux-api is installed but the termux:api app is missing
echo "$output" | busybox timeout -t 3 termux-clipboard-set 2>/dev/null echo "$output" | timeout 3 termux-clipboard-set 2>/dev/null
busybox timeout -t 3 termux-toast "Information has been copied to the clipboard" 2>/dev/null timeout 3 termux-toast "Information has been copied to the clipboard" 2>/dev/null
fi
exit 0 exit 0

Loading…
Cancel
Save