* tests/local.mk: reference the new test. * tests/chgrp/preserve-root.sh: the new file. --- tests/chgrp/preserve-root.sh | 84 ++++++++++++++++++++++++++++++++++++ tests/local.mk | 1 + 2 files changed, 85 insertions(+) create mode 100755 tests/chgrp/preserve-root.sh
diff --git a/tests/chgrp/preserve-root.sh b/tests/chgrp/preserve-root.sh new file mode 100755 index 000000000..96f4e110c --- /dev/null +++ b/tests/chgrp/preserve-root.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# Test --preserve-root and --no-preserve-root options + +# Copyright (C) 2026 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +srcdir=$PWD +. "${srcdir}/tests/init.sh"; path_prepend_ ./src +print_ver_ chgrp +require_root_ + +# Create a safe chroot environment for testing +chroot_dir="$PWD/chroot_test" +mkdir -p "$chroot_dir"/{bin,lib,lib64,etc,dev,tmp} || framework_failure_ +# Copy essential files for chroot to work +cp /bin/sh "$chroot_dir/bin/" 2>/dev/null || \ + cp /usr/bin/sh "$chroot_dir/bin/sh" 2>/dev/null || framework_failure_ + +# Copy required libraries if any +ldd $chroot_dir/bin/sh 2>/dev/null | grep -o '/lib[^ ]*' | while read lib; do + test -f "$lib" && cp "$lib" "$chroot_dir/lib/" 2>/dev/null || true +done + +pwd +# Copy chgrp binary to chroot +cp ${srcdir}/src/chgrp "$chroot_dir/bin/chgrp" || framework_failure_ + +# Copy chgrp's required libraries +ldd $chroot_dir/bin/chgrp | grep -o '/lib[^ ]*' | while read lib; do + test -f "$lib" && cp "$lib" "$chroot_dir/lib/" 2>/dev/null || true + test -f "$lib" && cp "$lib" "$chroot_dir/lib64/" 2>/dev/null || true +done + +# Create minimal device nodes +mknod "$chroot_dir/dev/null" c 1 3 2>/dev/null || true +chmod 666 "$chroot_dir/dev/null" 2>/dev/null || true + +# Test 1: --preserve-root should refuse recursive operation on / +echo "=== Test 1: preserve-root on / ===" >&2 +chroot "$chroot_dir" /bin/chgrp -R --preserve-root 1 / 2>out && fail=1 +echo "=== Test 1 output ===" >&2 +cat out >&2 +echo "=== End Test 1 output ===" >&2 +grep "it is dangerous to operate recursively.*'/'" out >/dev/null || fail=1 + +# Test 2: --no-preserve-root should allow the operation +chroot "$chroot_dir" /bin/chgrp -R --no-preserve-root 1 / 2>out || true +grep "it is dangerous to operate recursively" out >/dev/null && fail=1 + +# Test 3: Default behavior should be --no-preserve-root +chroot "$chroot_dir" /bin/chgrp -R 1 / 2>out || true +grep "it is dangerous to operate recursively" out >/dev/null && fail=1 + +# Test 4: Verify preserve-root works correctly +chroot "$chroot_dir" /bin/chgrp -R --preserve-root 1 / 2>out && fail=1 +grep "it is dangerous to operate recursively.*'/'" out >/dev/null || fail=1 + +# Test 5: Verify --no-preserve-root with symlink options +# Re-create directory structure in case it was modified by previous tests +rm -rf "$chroot_dir/dir_link" +mkdir -p "$chroot_dir/dir_link" || framework_failure_ +ln -s / "$chroot_dir/dir_link/sym_link" || framework_failure_ + +chroot "$chroot_dir" /bin/chgrp -R -H --no-preserve-root 1 /dir_link/sym_link 2>out || true +grep "it is dangerous to operate recursively" out >/dev/null && fail=1 + +chroot "$chroot_dir" /bin/chgrp -R -L --no-preserve-root 1 /dir_link/ 2>out || true +grep "it is dangerous to operate recursively" out >/dev/null && fail=1 + +# the group of files within chroot should be daemon or bin +ls -l "$chroot_dir/" + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk index 9414dbf9d..0e0ca3fa5 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -108,6 +108,7 @@ EXTRA_DIST += \ all_root_tests = \ tests/chown/basic.sh \ tests/chgrp/from.sh \ + tests/chgrp/preserve-root.sh \ tests/cp/cp-a-selinux.sh \ tests/cp/preserve-gid.sh \ tests/cp/special-bits.sh \ -- 2.43.0
