Date: Sat, 27 Apr 2024 14:58:48 GMT From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= <des@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 17997507040c - stable/13 - cp: Clarify an obscure comment. Message-ID: <202404271458.43REwmsr032620@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=17997507040c4ad1c6a25ce93c3981ee19ce28c0 commit 17997507040c4ad1c6a25ce93c3981ee19ce28c0 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2024-04-17 01:36:22 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2024-04-27 14:58:40 +0000 cp: Clarify an obscure comment. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D44805 (cherry picked from commit 64d6925d1901637125f9f739282e72c992657dc8) cp: Additional sanity check. Once we've successfully opened the file we've been asked to copy, check that it's of the same type as FTS told us it was. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude, markj Differential Revision: https://reviews.freebsd.org/D44806 (cherry picked from commit 9075d4cfad5b339aabdf8033623a2164898c2786) cp: Use warnc(). MFC after: 1 week Sponsored by: Klara, Inc. (cherry picked from commit f070188c3ad6b87ee9ce220b21718333d1bd9d52) --- bin/cp/cp.c | 13 +++++++++---- bin/cp/utils.c | 27 ++++++++++++++++++++------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/bin/cp/cp.c b/bin/cp/cp.c index af7d5ffac398..a8c57308ae96 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -316,8 +316,7 @@ copy(char *argv[], enum op type, int fts_options, struct stat *root_stat) case FTS_NS: case FTS_DNR: case FTS_ERR: - warnx("%s: %s", - curr->fts_path, strerror(curr->fts_errno)); + warnc(curr->fts_errno, "%s", curr->fts_path); badcp = rval = 1; continue; case FTS_DC: /* Warn, continue. */ @@ -491,13 +490,19 @@ copy(char *argv[], enum op type, int fts_options, struct stat *root_stat) switch (curr->fts_statp->st_mode & S_IFMT) { case S_IFLNK: - /* Catch special case of a non-dangling symlink. */ if ((fts_options & FTS_LOGICAL) || ((fts_options & FTS_COMFOLLOW) && curr->fts_level == 0)) { + /* + * We asked FTS to follow links but got + * here anyway, which means the target is + * nonexistent or inaccessible. Let + * copy_file() deal with the error. + */ if (copy_file(curr, dne)) badcp = rval = 1; - } else { + } else { + /* Copy the link. */ if (copy_link(curr, !dne)) badcp = rval = 1; } diff --git a/bin/cp/utils.c b/bin/cp/utils.c index 0bb5157e3f57..9f6ef888c7ea 100644 --- a/bin/cp/utils.c +++ b/bin/cp/utils.c @@ -106,21 +106,34 @@ copy_fallback(int from_fd, int to_fd) int copy_file(const FTSENT *entp, int dne) { - struct stat *fs; + struct stat sb, *fs; ssize_t wcount; off_t wtotal; int ch, checkch, from_fd, rval, to_fd; int use_copy_file_range = 1; + fs = entp->fts_statp; from_fd = to_fd = -1; - if (!lflag && !sflag && - (from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) { - warn("%s", entp->fts_path); - return (1); + if (!lflag && !sflag) { + if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) < 0 || + fstat(from_fd, &sb) != 0) { + warn("%s", entp->fts_path); + return (1); + } + /* + * Check that the file hasn't been replaced with one of a + * different type. This can happen if we've been asked to + * copy something which is actively being modified and + * lost the race, or if we've been asked to copy something + * like /proc/X/fd/Y which stat(2) reports as S_IFREG but + * is actually something else once you open it. + */ + if ((sb.st_mode & S_IFMT) != (fs->st_mode & S_IFMT)) { + warnx("%s: File changed", entp->fts_path); + return (1); + } } - fs = entp->fts_statp; - /* * If the file exists and we're interactive, verify with the user. * If the file DNE, set the mode to be the from file, minus setuid
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202404271458.43REwmsr032620>