109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From dce4683cbbe107a95f1f0d45fabc304acfb5d71a Mon Sep 17 00:00:00 2001
 | |
| From: Andreas Gruenbacher <agruen@gnu.org>
 | |
| Date: Mon, 15 Jul 2019 16:21:48 +0200
 | |
| Subject: Don't follow symlinks unless --follow-symlinks is given
 | |
| 
 | |
| * src/inp.c (plan_a, plan_b), src/util.c (copy_to_fd, copy_file,
 | |
| append_to_file): Unless the --follow-symlinks option is given, open files with
 | |
| the O_NOFOLLOW flag to avoid following symlinks.  So far, we were only doing
 | |
| that consistently for input files.
 | |
| * src/util.c (create_backup): When creating empty backup files, (re)create them
 | |
| with O_CREAT | O_EXCL to avoid following symlinks in that case as well.
 | |
| ---
 | |
|  src/inp.c  | 12 ++++++++++--
 | |
|  src/util.c | 14 +++++++++++---
 | |
|  2 files changed, 21 insertions(+), 5 deletions(-)
 | |
| 
 | |
| diff --git a/src/inp.c b/src/inp.c
 | |
| index 32d0919..22d7473 100644
 | |
| --- a/src/inp.c
 | |
| +++ b/src/inp.c
 | |
| @@ -238,8 +238,13 @@ plan_a (char const *filename)
 | |
|      {
 | |
|        if (S_ISREG (instat.st_mode))
 | |
|          {
 | |
| -	  int ifd = safe_open (filename, O_RDONLY|binary_transput, 0);
 | |
| +	  int flags = O_RDONLY | binary_transput;
 | |
|  	  size_t buffered = 0, n;
 | |
| +	  int ifd;
 | |
| +
 | |
| +	  if (! follow_symlinks)
 | |
| +	    flags |= O_NOFOLLOW;
 | |
| +	  ifd = safe_open (filename, flags, 0);
 | |
|  	  if (ifd < 0)
 | |
|  	    pfatal ("can't open file %s", quotearg (filename));
 | |
|  
 | |
| @@ -340,6 +345,7 @@ plan_a (char const *filename)
 | |
|  static void
 | |
|  plan_b (char const *filename)
 | |
|  {
 | |
| +  int flags = O_RDONLY | binary_transput;
 | |
|    int ifd;
 | |
|    FILE *ifp;
 | |
|    int c;
 | |
| @@ -353,7 +359,9 @@ plan_b (char const *filename)
 | |
|  
 | |
|    if (instat.st_size == 0)
 | |
|      filename = NULL_DEVICE;
 | |
| -  if ((ifd = safe_open (filename, O_RDONLY | binary_transput, 0)) < 0
 | |
| +  if (! follow_symlinks)
 | |
| +    flags |= O_NOFOLLOW;
 | |
| +  if ((ifd = safe_open (filename, flags, 0)) < 0
 | |
|        || ! (ifp = fdopen (ifd, binary_transput ? "rb" : "r")))
 | |
|      pfatal ("Can't open file %s", quotearg (filename));
 | |
|    if (TMPINNAME_needs_removal)
 | |
| diff --git a/src/util.c b/src/util.c
 | |
| index 1cc08ba..fb38307 100644
 | |
| --- a/src/util.c
 | |
| +++ b/src/util.c
 | |
| @@ -388,7 +388,7 @@ create_backup (char const *to, const struct stat *to_st, bool leave_original)
 | |
|  
 | |
|  	  try_makedirs_errno = ENOENT;
 | |
|  	  safe_unlink (bakname);
 | |
| -	  while ((fd = safe_open (bakname, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0)
 | |
| +	  while ((fd = safe_open (bakname, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, 0666)) < 0)
 | |
|  	    {
 | |
|  	      if (errno != try_makedirs_errno)
 | |
|  		pfatal ("Can't create file %s", quotearg (bakname));
 | |
| @@ -579,10 +579,13 @@ create_file (char const *file, int open_flags, mode_t mode,
 | |
|  static void
 | |
|  copy_to_fd (const char *from, int tofd)
 | |
|  {
 | |
| +  int from_flags = O_RDONLY | O_BINARY;
 | |
|    int fromfd;
 | |
|    ssize_t i;
 | |
|  
 | |
| -  if ((fromfd = safe_open (from, O_RDONLY | O_BINARY, 0)) < 0)
 | |
| +  if (! follow_symlinks)
 | |
| +    from_flags |= O_NOFOLLOW;
 | |
| +  if ((fromfd = safe_open (from, from_flags, 0)) < 0)
 | |
|      pfatal ("Can't reopen file %s", quotearg (from));
 | |
|    while ((i = read (fromfd, buf, bufsize)) != 0)
 | |
|      {
 | |
| @@ -625,6 +628,8 @@ copy_file (char const *from, char const *to, struct stat *tost,
 | |
|    else
 | |
|      {
 | |
|        assert (S_ISREG (mode));
 | |
| +      if (! follow_symlinks)
 | |
| +	to_flags |= O_NOFOLLOW;
 | |
|        tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode,
 | |
|  			  to_dir_known_to_exist);
 | |
|        copy_to_fd (from, tofd);
 | |
| @@ -640,9 +645,12 @@ copy_file (char const *from, char const *to, struct stat *tost,
 | |
|  void
 | |
|  append_to_file (char const *from, char const *to)
 | |
|  {
 | |
| +  int to_flags = O_WRONLY | O_APPEND | O_BINARY;
 | |
|    int tofd;
 | |
|  
 | |
| -  if ((tofd = safe_open (to, O_WRONLY | O_BINARY | O_APPEND, 0)) < 0)
 | |
| +  if (! follow_symlinks)
 | |
| +    to_flags |= O_NOFOLLOW;
 | |
| +  if ((tofd = safe_open (to, to_flags, 0)) < 0)
 | |
|      pfatal ("Can't reopen file %s", quotearg (to));
 | |
|    copy_to_fd (from, tofd);
 | |
|    if (close (tofd) != 0)
 | |
| -- 
 | |
| cgit v1.0-41-gc330
 | |
| 
 | 
