[prev in list] [next in list] [prev in thread] [next in thread] 

List:       nano-devel
Subject:    [Nano-devel] [PATCH] pull in the futimens module from gnulib
From:       Kamil Dudka <kdudka () redhat ! com>
Date:       2017-03-31 11:45:49
Message-ID: 20170331114549.25142-1-kdudka () redhat ! com
[Download RAW message or body]

... and use futimens() instead of utime() to prevent a symlink attack
while creating a backup file.  Otherwise, a non-privileged user could
create an arbitrary symlink with name of the backup file and this way
fool a privileged user to call utime() on the attacker-chosen file.
---
 autogen.sh  |  1 +
 src/files.c | 28 ++++++++++++++--------------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/autogen.sh b/autogen.sh
index 617705c..de9f3bb 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -5,6 +5,7 @@ gnulib_url="git://git.sv.gnu.org/gnulib.git"
 gnulib_hash="4084b3a1094372b960ce4a97634e08f4538c8bdd"
 
 modules="
+	futimens
 	getdelim
 	getline
 	getopt-gnu
diff --git a/src/files.c b/src/files.c
index 033b963..644b8a1 100644
--- a/src/files.c
+++ b/src/files.c
@@ -1655,13 +1655,13 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
 	int backup_fd;
 	FILE *backup_file;
 	char *backupname;
-	struct utimbuf filetime;
+	static struct timespec filetime[2];
 	int copy_status;
 	int backup_cflags;
 
 	/* Save the original file's access and modification times. */
-	filetime.actime = openfile->current_stat->st_atime;
-	filetime.modtime = openfile->current_stat->st_mtime;
+	filetime[/* atime */ 0].tv_sec = openfile->current_stat->st_atime;
+	filetime[/* mtime */ 1].tv_sec = openfile->current_stat->st_mtime;
 
 	if (f_open == NULL) {
 	    /* Open the original file to copy to the backup. */
@@ -1789,17 +1789,8 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
 	fprintf(stderr, "Backing up %s to %s\n", realname, backupname);
 #endif
 
-	/* Copy the file. */
-	copy_status = copy_file(f, backup_file);
-
-	if (copy_status != 0) {
-	    statusline(ALERT, _("Error reading %s: %s"), realname,
-			strerror(errno));
-	    goto cleanup_and_exit;
-	}
-
-	/* And set its metadata. */
-	if (utime(backupname, &filetime) == -1 && !ISSET(INSECURE_BACKUP)) {
+	/* Set backup's file metadata. */
+	if (futimens(backup_fd, filetime) == -1 && !ISSET(INSECURE_BACKUP)) {
 	    if (prompt_failed_backupwrite(backupname))
 		goto skip_backup;
 	    statusline(HUSH, _("Error writing backup file %s: %s"),
@@ -1811,6 +1802,15 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
 	    goto cleanup_and_exit;
 	}
 
+	/* Copy the file. */
+	copy_status = copy_file(f, backup_file);
+
+	if (copy_status != 0) {
+	    statusline(ALERT, _("Error reading %s: %s"), realname,
+			strerror(errno));
+	    goto cleanup_and_exit;
+	}
+
 	free(backupname);
     }
 
-- 
2.9.3


_______________________________________________
Nano-devel mailing list
Nano-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/nano-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic