Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Dec 2015 20:41:45 +0000 (UTC)
From:      Baptiste Daroussin <bapt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r291823 - stable/10/usr.bin/xinstall
Message-ID:  <201512042041.tB4Kfj7T063934@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bapt
Date: Fri Dec  4 20:41:44 2015
New Revision: 291823
URL: https://svnweb.freebsd.org/changeset/base/291823

Log:
  MFC: r291091
  
  install: do not follow symlinks
  
  In case the target of install is a dead symlink, install(1) used to not
  consider it as "existing" because of the usage of stat(2) instead of
  lstat(2).  meaning the old file (the symlink) is not removed before the new
  file is created. The symlink is being followed and the new file becoming the
  target of the symlink instead of the target of install(1)
  
  Reviewed by:	jhb, brooks
  Differential Revision:	https://reviews.freebsd.org/D4191

Modified:
  stable/10/usr.bin/xinstall/xinstall.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.bin/xinstall/xinstall.c
==============================================================================
--- stable/10/usr.bin/xinstall/xinstall.c	Fri Dec  4 20:12:49 2015	(r291822)
+++ stable/10/usr.bin/xinstall/xinstall.c	Fri Dec  4 20:41:44 2015	(r291823)
@@ -748,10 +748,7 @@ install(const char *from_name, const cha
 		devnull = 1;
 	}
 
-	if (!dolink)
-		target = (stat(to_name, &to_sb) == 0);
-	else
-		target = (lstat(to_name, &to_sb) == 0);
+	target = (lstat(to_name, &to_sb) == 0);
 
 	if (dolink) {
 		if (target && !safecopy) {
@@ -766,8 +763,7 @@ install(const char *from_name, const cha
 		return;
 	}
 
-	/* Only install to regular files. */
-	if (target && !S_ISREG(to_sb.st_mode)) {
+	if (target && !S_ISREG(to_sb.st_mode) && !S_ISLNK(to_sb.st_mode)) {
 		errno = EFTYPE;
 		warn("%s", to_name);
 		return;
@@ -780,7 +776,7 @@ install(const char *from_name, const cha
 		err(EX_OSERR, "%s", from_name);
 
 	/* If we don't strip, we can compare first. */
-	if (docompare && !dostrip && target) {
+	if (docompare && !dostrip && target && S_ISREG(to_sb.st_mode)) {
 		if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
 			err(EX_OSERR, "%s", to_name);
 		if (devnull)
@@ -832,7 +828,7 @@ install(const char *from_name, const cha
 	/*
 	 * Compare the stripped temp file with the target.
 	 */
-	if (docompare && dostrip && target) {
+	if (docompare && dostrip && target && S_ISREG(to_sb.st_mode)) {
 		temp_fd = to_fd;
 
 		/* Re-open to_fd using the real target name. */
@@ -866,9 +862,7 @@ install(const char *from_name, const cha
 			}
 			(void) close(temp_fd);
 		}
-	}
-
-	if (dostrip && (!docompare || !target))
+	} else if (dostrip)
 		digestresult = digest_file(tempfile);
 
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512042041.tB4Kfj7T063934>