1#!/bin/sh 2# Make sure cp -p isn't too generous with existing file permissions. 3 4# Copyright (C) 2006-2023 Free Software Foundation, Inc. 5 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <https://www.gnu.org/licenses/>. 18 19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 20print_ver_ cp 21 22require_membership_in_two_groups_ 23 24# cp -p gives ENOTSUP on NFS on Linux 2.6.9 at least 25require_local_dir_ 26 27require_no_default_acl_ . 28 29set _ $groups; shift 30g1=$1 31g2=$2 32 33 34umask 077 35mkfifo_or_skip_ fifo 36 37touch fifo-copy && 38chgrp $g1 fifo && 39chgrp $g2 fifo-copy && 40chmod g+r fifo-copy || framework-failure 41 42# Terminate any background cp process 43cleanup_() { kill $pid 2>/dev/null && wait $pid; } 44 45# Copy a fifo's contents. That way, we can examine the 46# destination permissions before they're finalized. 47cp -p --copy-contents fifo fifo-copy & pid=$! 48 49( 50 # Now 'cp' is reading the fifo. Wait for the destination file to 51 # be written to, encouraging things along by echoing to the fifo. 52 while test ! -s fifo-copy; do 53 echo foo 54 done 55 56 # Check the permissions of the destination. 57 ls -l -n fifo-copy >ls.out && 58 59 # Close the fifo so that "cp" can continue. But output first, 60 # before exiting, otherwise some shells would optimize away the file 61 # descriptor that holds the fifo open. 62 echo foo 63) >fifo || fail=1 64 65# Check that the destination mode is safe while the file is being copied. 66read mode links owner group etc <ls.out || fail=1 67case $mode in 68 -rw-------*) ;; 69 70 # FIXME: Remove the following case; the file mode should always be 71 # 600 while the data are being copied. This will require changing 72 # cp so that it also does not put $g1's data in a file that is 73 # accessible to $g2. This fix will not close a security hole, since 74 # a $g2 process can maintain an open file descriptor to the 75 # destination, but it's safer anyway. 76 -rw-r-----*) 77 # If the file has group $g1 and is group-readable, that is definitely bogus, 78 # as neither the source nor the destination was readable to group $g1. 79 test "$group" = "$g1" && fail=1;; 80 81 *) fail=1;; 82esac 83 84wait $pid || fail=1 85 86# Check that the final mode and group are right. 87ls -l -n fifo-copy >ls.out && 88read mode links owner group etc <ls.out || fail=1 89case $mode in 90 -rw-------*) test "$group" = "$g1" || fail=1;; 91 *) fail=1;; 92esac 93 94Exit $fail 95