tmpfiles: propagate copy errors after opening target
Opening the destination only proves that it exists. If copy_tree_at()
failed for any reason other than an existing destination, report that
copy error.
Reproducer:
name=tmpfiles-copy-bug.$$
src=/tmp/$name.src; dst=/tmp/$name.dst; conf=/tmp/$name.conf
mkdir "$src" "$dst"
printf payload >"$src/file"
chmod 500 "$dst"
printf 'C %s - - - - %s\n' "$dst" "$src" >"$conf"
systemd-tmpfiles --create "$conf"
Before:
exit=0
copied=no
Follow-up for 8f6fb95cd0.
This commit is contained in:
@@ -2238,6 +2238,9 @@ static int copy_files(Context *c, Item *i) {
|
||||
return log_error_errno(errno, "Failed to openat(%s): %m", i->path);
|
||||
}
|
||||
|
||||
if (r < 0 && !IN_SET(r, -EEXIST, -EROFS))
|
||||
return log_error_errno(r, "Failed to copy files to %s: %m", i->path);
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to fstat(%s): %m", i->path);
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
# shellcheck source=test/units/util.sh
|
||||
. "$(dirname "$0")"/util.sh
|
||||
|
||||
rm -fr /tmp/{f,F,w}
|
||||
mkdir /tmp/{f,F,w}
|
||||
touch /tmp/file-owned-by-root
|
||||
@@ -190,6 +193,22 @@ F /tmp/F/daemon/unsafe-symlink/exploit 0644 daemon daemon - -
|
||||
EOF
|
||||
test ! -e /tmp/F/daemon/unsafe-symlink/exploit
|
||||
|
||||
#
|
||||
# 'C'
|
||||
#
|
||||
rm -rf /tmp/C-copy-failure-src /tmp/C-copy-failure-dst
|
||||
mkdir /tmp/C-copy-failure-src /tmp/C-copy-failure-dst
|
||||
printf payload >/tmp/C-copy-failure-src/file
|
||||
chmod 555 /tmp/C-copy-failure-dst
|
||||
|
||||
(! runas nobody systemd-tmpfiles --create - <<EOF
|
||||
C /tmp/C-copy-failure-dst - - - - /tmp/C-copy-failure-src
|
||||
EOF
|
||||
)
|
||||
test ! -e /tmp/C-copy-failure-dst/file
|
||||
chmod 755 /tmp/C-copy-failure-dst
|
||||
rm -rf /tmp/C-copy-failure-src /tmp/C-copy-failure-dst
|
||||
|
||||
#
|
||||
# 'w'
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user