* tests/rm/fail-eperm.xpl: Remove this usually skipped non-root test. * tests/rm/fail-2eperm.sh: Add the test to this root test instead. * tests/local.mk: Remove the reference to *.xpl. --- tests/local.mk | 3 +- tests/rm/fail-2eperm.sh | 28 ++++---- tests/rm/fail-eperm.xpl | 150 ---------------------------------------- 3 files changed, 17 insertions(+), 164 deletions(-) delete mode 100755 tests/rm/fail-eperm.xpl
diff --git a/tests/local.mk b/tests/local.mk index 4ae003719..b7fb84e3e 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -23,7 +23,7 @@ root_tests = $(all_root_tests) EXTRA_DIST += $(all_tests) -TEST_EXTENSIONS = .sh .pl .xpl +TEST_EXTENSIONS = .sh .pl if HAVE_PERL TESTSUITE_PERL = $(PERL) @@ -207,7 +207,6 @@ all_tests = \ tests/rm/empty-name.pl \ tests/rm/f-1.sh \ tests/rm/fail-eacces.sh \ - tests/rm/fail-eperm.xpl \ tests/tail/assert.sh \ tests/rm/hash.sh \ tests/rm/i-1.sh \ diff --git a/tests/rm/fail-2eperm.sh b/tests/rm/fail-2eperm.sh index f23c89164..3d16f3baa 100755 --- a/tests/rm/fail-2eperm.sh +++ b/tests/rm/fail-2eperm.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Like fail-eperm, but the failure must be for a file encountered -# while trying to remove the containing directory with the sticky bit set. +# Ensure that rm gives the expected diagnostic when failing to remove a file +# owned by some other user in a directory with the sticky bit set. # Copyright (C) 2003-2025 Free Software Foundation, Inc. @@ -40,18 +40,22 @@ case $rm_version in $PACKAGE_VERSION) ;; *) skip_ "cannot access just-built rm as user $NON_ROOT_USERNAME";; esac -chroot --skip-chdir --user=$NON_ROOT_USERNAME / \ - env PATH="$PATH" rm -rf a 2> out-t && fail=1 -# On some systems, we get 'Not owner'. Convert it. -# On other systems (HPUX), we get 'Permission denied'. Convert it, too. -onp='Operation not permitted' -sed "s/Not owner/$onp/;s/Permission denied/$onp/" out-t > out -cat <<\EOF > exp -rm: cannot remove 'a/b': Operation not permitted -EOF +# Ensure that rm gives the expected diagnostic when +# failing to remove the file directly, or when traversed +for file in 'a/b' 'a'; do + echo "$file" | grep / && recurse='-r' + returns_ 1 chroot --skip-chdir --user=$NON_ROOT_USERNAME / \ + env PATH="$PATH" rm $recurse -f "$file" 2> out-t || fail=1 -compare exp out || fail=1 + # On some systems, we get 'Not owner'. Convert it. + # On other systems (HPUX), we get 'Permission denied'. Convert it, too. + onp='Operation not permitted' + sed "s/Not owner/$onp/;s/Permission denied/$onp/" out-t > out + + echo "rm: cannot remove 'a/b': Operation not permitted" > exp + compare exp out || fail=1 +done Exit $fail diff --git a/tests/rm/fail-eperm.xpl b/tests/rm/fail-eperm.xpl deleted file mode 100755 index ab75630a8..000000000 --- a/tests/rm/fail-eperm.xpl +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/perl -Tw -# Ensure that rm gives the expected diagnostic when failing to remove a file -# owned by some other user in a directory with the sticky bit set. - -# Copyright (C) 2002-2025 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/>. - -use strict; - -(my $ME = $0) =~ s|.*/||; - -my $uid = $<; -# skip if root -$uid == 0 - and CuSkip::skip "$ME: can't run this test as root: skipping this test"; - -my $verbose = $ENV{VERBOSE} && $ENV{VERBOSE} eq 'yes'; - -# Ensure that the diagnostics are in English. -$ENV{LC_ALL} = 'C'; - -# Set up a safe, well-known environment -$ENV{IFS} = ''; - -# Taint checking requires a sanitized $PATH. This script performs no $PATH -# search, so on most Unix-based systems, it is fine simply to clear $ENV{PATH}. -# However, on Cygwin, it's used to find cygwin1.dll, so set it. -$ENV{PATH} = '/bin:/usr/bin'; - -my @dir_list = qw(/tmp /var/tmp /usr/tmp); -my $rm = "$ENV{abs_top_builddir}/src/rm"; - -# Untaint for upcoming popen. -$rm =~ m!^([-+\@\w./]+)$! - or CuSkip::skip "$ME: unusual absolute builddir name; skipping this test\n"; -$rm = $1; - -# Find a directory with the sticky bit set. -my $found_dir; -my $found_file; -foreach my $dir (@dir_list) - { - if (-d $dir && -k _ && -r _ && -w _ && -x _) - { - $found_dir = 1; - - # Find a non-directory there that is owned by some other user. - opendir DIR_HANDLE, $dir - or die "$ME: couldn't open $dir: $!\n"; - - foreach my $f (readdir DIR_HANDLE) - { - # Consider only names containing "safe" characters. - $f =~ /^([-\@\w.]+)$/ - or next; - $f = $1; # untaint $f - - my $target_file = "$dir/$f"; - $verbose - and warn "$ME: considering $target_file\n"; - - # Skip files owned by self, symlinks, and directories. - # It's not technically necessary to skip symlinks, but it's simpler. - # SVR4-like systems (e.g., Solaris 9) let you unlink files that - # you can write, so skip writable files too. - -l $target_file || -o _ || -d _ || -w _ - and next; - - $found_file = 1; - - # Invoke rm on this file and ensure that we get the - # expected exit code and diagnostic. - my $cmd = "$rm -f -- $target_file"; - open RM, "$cmd 2>&1 |" - or die "$ME: cannot execute '$cmd'\n"; - - my $line = <RM>; - - close RM; - my $rc = $?; - # This test opportunistically looks for files that can't - # be removed but those files may already have been removed - # by their owners by the time we get to them. It is a - # race condition. If so then the rm is successful and our - # test is thwarted. Detect this case and ignore. - if ($rc == 0) - { - next if ! -e $target_file; - die "$ME: unexpected exit status from '$cmd';\n" - . " got 0, expected 1\n"; - } - if (0x80 < $rc) - { - my $status = $rc >> 8; - $status == 1 - or die "$ME: unexpected exit status from '$cmd';\n" - . " got $status, expected 1\n"; - } - else - { - # Terminated by a signal. - my $sig_num = $rc & 0x7F; - die "$ME: command '$cmd' died with signal $sig_num\n"; - } - - my $exp = "rm: cannot remove '$target_file':"; - $line - or die "$ME: no output from '$cmd';\n" - . "expected something like '$exp ...'\n"; - - # Transform the actual diagnostic so that it starts with "rm:". - # Depending on your system, it might be "rm:" already, or - # "../../src/rm:". - $line =~ s,^\Q$rm\E:,rm:,; - - my $regex = quotemeta $exp; - $line =~ /^$regex/ - or die "$ME: unexpected diagnostic from '$cmd';\n" - . " got $line" - . " expected $exp ...\n"; - - last; - } - - closedir DIR_HANDLE; - $found_file - and last; - } - } - -$found_dir - or CuSkip::skip "$ME: couldn't find a directory with the sticky bit set;" - . " skipping this test\n"; - -$found_file - or CuSkip::skip "$ME: couldn't find a file not owned by you\n" - . " in any of the following directories:\n @dir_list\n" - . "...so, skipping this test\n"; -- 2.51.1
