1*4882a593SmuzhiyunFrom dce4683cbbe107a95f1f0d45fabc304acfb5d71a Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Andreas Gruenbacher <agruen@gnu.org>
3*4882a593SmuzhiyunDate: Mon, 15 Jul 2019 16:21:48 +0200
4*4882a593SmuzhiyunSubject: Don't follow symlinks unless --follow-symlinks is given
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun* src/inp.c (plan_a, plan_b), src/util.c (copy_to_fd, copy_file,
7*4882a593Smuzhiyunappend_to_file): Unless the --follow-symlinks option is given, open files with
8*4882a593Smuzhiyunthe O_NOFOLLOW flag to avoid following symlinks.  So far, we were only doing
9*4882a593Smuzhiyunthat consistently for input files.
10*4882a593Smuzhiyun* src/util.c (create_backup): When creating empty backup files, (re)create them
11*4882a593Smuzhiyunwith O_CREAT | O_EXCL to avoid following symlinks in that case as well.
12*4882a593Smuzhiyun[Retrieved from:
13*4882a593Smuzhiyunhttps://git.savannah.gnu.org/cgit/patch.git/commit/?id=dce4683cbbe107a95f1f0d45fabc304acfb5d71a]
14*4882a593SmuzhiyunSigned-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
15*4882a593Smuzhiyun---
16*4882a593Smuzhiyun src/inp.c  | 12 ++++++++++--
17*4882a593Smuzhiyun src/util.c | 14 +++++++++++---
18*4882a593Smuzhiyun 2 files changed, 21 insertions(+), 5 deletions(-)
19*4882a593Smuzhiyun
20*4882a593Smuzhiyundiff --git a/src/inp.c b/src/inp.c
21*4882a593Smuzhiyunindex 32d0919..22d7473 100644
22*4882a593Smuzhiyun--- a/src/inp.c
23*4882a593Smuzhiyun+++ b/src/inp.c
24*4882a593Smuzhiyun@@ -238,8 +238,13 @@ plan_a (char const *filename)
25*4882a593Smuzhiyun     {
26*4882a593Smuzhiyun       if (S_ISREG (instat.st_mode))
27*4882a593Smuzhiyun         {
28*4882a593Smuzhiyun-	  int ifd = safe_open (filename, O_RDONLY|binary_transput, 0);
29*4882a593Smuzhiyun+	  int flags = O_RDONLY | binary_transput;
30*4882a593Smuzhiyun 	  size_t buffered = 0, n;
31*4882a593Smuzhiyun+	  int ifd;
32*4882a593Smuzhiyun+
33*4882a593Smuzhiyun+	  if (! follow_symlinks)
34*4882a593Smuzhiyun+	    flags |= O_NOFOLLOW;
35*4882a593Smuzhiyun+	  ifd = safe_open (filename, flags, 0);
36*4882a593Smuzhiyun 	  if (ifd < 0)
37*4882a593Smuzhiyun 	    pfatal ("can't open file %s", quotearg (filename));
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun@@ -340,6 +345,7 @@ plan_a (char const *filename)
40*4882a593Smuzhiyun static void
41*4882a593Smuzhiyun plan_b (char const *filename)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun+  int flags = O_RDONLY | binary_transput;
44*4882a593Smuzhiyun   int ifd;
45*4882a593Smuzhiyun   FILE *ifp;
46*4882a593Smuzhiyun   int c;
47*4882a593Smuzhiyun@@ -353,7 +359,9 @@ plan_b (char const *filename)
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun   if (instat.st_size == 0)
50*4882a593Smuzhiyun     filename = NULL_DEVICE;
51*4882a593Smuzhiyun-  if ((ifd = safe_open (filename, O_RDONLY | binary_transput, 0)) < 0
52*4882a593Smuzhiyun+  if (! follow_symlinks)
53*4882a593Smuzhiyun+    flags |= O_NOFOLLOW;
54*4882a593Smuzhiyun+  if ((ifd = safe_open (filename, flags, 0)) < 0
55*4882a593Smuzhiyun       || ! (ifp = fdopen (ifd, binary_transput ? "rb" : "r")))
56*4882a593Smuzhiyun     pfatal ("Can't open file %s", quotearg (filename));
57*4882a593Smuzhiyun   if (TMPINNAME_needs_removal)
58*4882a593Smuzhiyundiff --git a/src/util.c b/src/util.c
59*4882a593Smuzhiyunindex 1cc08ba..fb38307 100644
60*4882a593Smuzhiyun--- a/src/util.c
61*4882a593Smuzhiyun+++ b/src/util.c
62*4882a593Smuzhiyun@@ -388,7 +388,7 @@ create_backup (char const *to, const struct stat *to_st, bool leave_original)
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun 	  try_makedirs_errno = ENOENT;
65*4882a593Smuzhiyun 	  safe_unlink (bakname);
66*4882a593Smuzhiyun-	  while ((fd = safe_open (bakname, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0)
67*4882a593Smuzhiyun+	  while ((fd = safe_open (bakname, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, 0666)) < 0)
68*4882a593Smuzhiyun 	    {
69*4882a593Smuzhiyun 	      if (errno != try_makedirs_errno)
70*4882a593Smuzhiyun 		pfatal ("Can't create file %s", quotearg (bakname));
71*4882a593Smuzhiyun@@ -579,10 +579,13 @@ create_file (char const *file, int open_flags, mode_t mode,
72*4882a593Smuzhiyun static void
73*4882a593Smuzhiyun copy_to_fd (const char *from, int tofd)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun+  int from_flags = O_RDONLY | O_BINARY;
76*4882a593Smuzhiyun   int fromfd;
77*4882a593Smuzhiyun   ssize_t i;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun-  if ((fromfd = safe_open (from, O_RDONLY | O_BINARY, 0)) < 0)
80*4882a593Smuzhiyun+  if (! follow_symlinks)
81*4882a593Smuzhiyun+    from_flags |= O_NOFOLLOW;
82*4882a593Smuzhiyun+  if ((fromfd = safe_open (from, from_flags, 0)) < 0)
83*4882a593Smuzhiyun     pfatal ("Can't reopen file %s", quotearg (from));
84*4882a593Smuzhiyun   while ((i = read (fromfd, buf, bufsize)) != 0)
85*4882a593Smuzhiyun     {
86*4882a593Smuzhiyun@@ -625,6 +628,8 @@ copy_file (char const *from, char const *to, struct stat *tost,
87*4882a593Smuzhiyun   else
88*4882a593Smuzhiyun     {
89*4882a593Smuzhiyun       assert (S_ISREG (mode));
90*4882a593Smuzhiyun+      if (! follow_symlinks)
91*4882a593Smuzhiyun+	to_flags |= O_NOFOLLOW;
92*4882a593Smuzhiyun       tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode,
93*4882a593Smuzhiyun 			  to_dir_known_to_exist);
94*4882a593Smuzhiyun       copy_to_fd (from, tofd);
95*4882a593Smuzhiyun@@ -640,9 +645,12 @@ copy_file (char const *from, char const *to, struct stat *tost,
96*4882a593Smuzhiyun void
97*4882a593Smuzhiyun append_to_file (char const *from, char const *to)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun+  int to_flags = O_WRONLY | O_APPEND | O_BINARY;
100*4882a593Smuzhiyun   int tofd;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun-  if ((tofd = safe_open (to, O_WRONLY | O_BINARY | O_APPEND, 0)) < 0)
103*4882a593Smuzhiyun+  if (! follow_symlinks)
104*4882a593Smuzhiyun+    to_flags |= O_NOFOLLOW;
105*4882a593Smuzhiyun+  if ((tofd = safe_open (to, to_flags, 0)) < 0)
106*4882a593Smuzhiyun     pfatal ("Can't reopen file %s", quotearg (to));
107*4882a593Smuzhiyun   copy_to_fd (from, tofd);
108*4882a593Smuzhiyun   if (close (tofd) != 0)
109*4882a593Smuzhiyun--
110*4882a593Smuzhiyuncgit v1.2.1
111*4882a593Smuzhiyun
112