[hackers] [sbase] [PATCH 07/11] cp: Only call chmod with -p or -a

From: Michael Forney <mforney_AT_mforney.org>
Date: Tue, 6 Dec 2016 02:16:59 -0800

Previously, when the destination file was created with fopen, we needed
to use fchmod to set its permissions.

Now that we pass in the mode to creat, we already get the desired
behavior of creating the file with the same mode as the source file
modified by the user's file creation mask.

This fixes the issue where a directory or special file created with
mkdir/mknod does not end up with the appropriate mode with -p or -a
(since it may have been narrowed by the umask).

This also allows us to clear the SUID and SGID bits from the mode if the
chown fails, as specified by POSIX.
---
 libutil/cp.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libutil/cp.c b/libutil/cp.c
index 8cd0a7d..339c892 100644
--- a/libutil/cp.c
+++ b/libutil/cp.c
_AT_@ -134,15 +134,11 @@ cp(const char *s1, const char *s2, int depth)
 			return 0;
 		}
 
-		/* preserve permissions by default */
-		fchmod(f2, st.st_mode);
-
 		close(f1);
 		close(f2);
 	}
 
 	if (cp_aflag || cp_pflag) {
-		/* timestamp and owner */
 		if (!S_ISLNK(st.st_mode)) {
 			times[0] = st.st_atim;
 			times[1] = st.st_mtim;
_AT_@ -151,7 +147,11 @@ cp(const char *s1, const char *s2, int depth)
 			if (chown(s2, st.st_uid, st.st_gid) < 0) {
 				weprintf("chown %s:", s2);
 				cp_status = 1;
-				return 0;
+				st.st_mode &= ~(S_ISUID | S_ISGID);
+			}
+			if (chmod(s2, st.st_mode) < 0) {
+				weprintf("chmod %s:", s2);
+				cp_status = 1;
 			}
 		} else {
 			if (lchown(s2, st.st_uid, st.st_gid) < 0) {
-- 
2.10.2
Received on Tue Dec 06 2016 - 11:16:59 CET

This archive was generated by hypermail 2.3.0 : Tue Dec 06 2016 - 11:24:43 CET