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