[CVE-2019-13636] Don't follow symlinks unless --follow-symlinks is given
authorAndreas Gruenbacher <agruen@gnu.org>
Mon, 15 Jul 2019 14:21:48 +0000 (16:21 +0200)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 16 May 2022 06:58:20 +0000 (15:58 +0900)
* 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.

Change-Id: Ic1ace0a9b9123cebd9e5a5f6c39bf69b85229fd9

src/inp.c
src/util.c

index 32d0919c1d1108b63c639a593108a560b9ae79f0..22d7473dce43ee1e127d1e2351906c21885c3985 100644 (file)
--- 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)
index b1c7266671b4cbc1065a711196ef434113cb246b..caac47f1ad9faa0cc335f97d028ebcc2c5b71d67 100644 (file)
@@ -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)