blob: d819838bba44f7f75f11c6badd0529235320feca [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From dce4683cbbe107a95f1f0d45fabc304acfb5d71a Mon Sep 17 00:00:00 2001
2From: Andreas Gruenbacher <agruen@gnu.org>
3Date: Mon, 15 Jul 2019 16:21:48 +0200
4Subject: Don't follow symlinks unless --follow-symlinks is given
5
6* src/inp.c (plan_a, plan_b), src/util.c (copy_to_fd, copy_file,
7append_to_file): Unless the --follow-symlinks option is given, open files with
8the O_NOFOLLOW flag to avoid following symlinks. So far, we were only doing
9that consistently for input files.
10* src/util.c (create_backup): When creating empty backup files, (re)create them
11with O_CREAT | O_EXCL to avoid following symlinks in that case as well.
12---
13 src/inp.c | 12 ++++++++++--
14 src/util.c | 14 +++++++++++---
15 2 files changed, 21 insertions(+), 5 deletions(-)
16
17--- a/src/inp.c
18+++ b/src/inp.c
19@@ -238,8 +238,13 @@ plan_a (char const *filename)
20 {
21 if (S_ISREG (instat.st_mode))
22 {
23- int ifd = safe_open (filename, O_RDONLY|binary_transput, 0);
24+ int flags = O_RDONLY | binary_transput;
25 size_t buffered = 0, n;
26+ int ifd;
27+
28+ if (! follow_symlinks)
29+ flags |= O_NOFOLLOW;
30+ ifd = safe_open (filename, flags, 0);
31 if (ifd < 0)
32 pfatal ("can't open file %s", quotearg (filename));
33
34@@ -340,6 +345,7 @@ plan_a (char const *filename)
35 static void
36 plan_b (char const *filename)
37 {
38+ int flags = O_RDONLY | binary_transput;
39 int ifd;
40 FILE *ifp;
41 int c;
42@@ -353,7 +359,9 @@ plan_b (char const *filename)
43
44 if (instat.st_size == 0)
45 filename = NULL_DEVICE;
46- if ((ifd = safe_open (filename, O_RDONLY | binary_transput, 0)) < 0
47+ if (! follow_symlinks)
48+ flags |= O_NOFOLLOW;
49+ if ((ifd = safe_open (filename, flags, 0)) < 0
50 || ! (ifp = fdopen (ifd, binary_transput ? "rb" : "r")))
51 pfatal ("Can't open file %s", quotearg (filename));
52 if (TMPINNAME_needs_removal)
53--- a/src/util.c
54+++ b/src/util.c
55@@ -388,7 +388,7 @@ create_backup (char const *to, const str
56
57 try_makedirs_errno = ENOENT;
58 safe_unlink (bakname);
59- while ((fd = safe_open (bakname, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0)
60+ while ((fd = safe_open (bakname, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, 0666)) < 0)
61 {
62 if (errno != try_makedirs_errno)
63 pfatal ("Can't create file %s", quotearg (bakname));
64@@ -579,10 +579,13 @@ create_file (char const *file, int open_
65 static void
66 copy_to_fd (const char *from, int tofd)
67 {
68+ int from_flags = O_RDONLY | O_BINARY;
69 int fromfd;
70 ssize_t i;
71
72- if ((fromfd = safe_open (from, O_RDONLY | O_BINARY, 0)) < 0)
73+ if (! follow_symlinks)
74+ from_flags |= O_NOFOLLOW;
75+ if ((fromfd = safe_open (from, from_flags, 0)) < 0)
76 pfatal ("Can't reopen file %s", quotearg (from));
77 while ((i = read (fromfd, buf, bufsize)) != 0)
78 {
79@@ -625,6 +628,8 @@ copy_file (char const *from, char const
80 else
81 {
82 assert (S_ISREG (mode));
83+ if (! follow_symlinks)
84+ to_flags |= O_NOFOLLOW;
85 tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode,
86 to_dir_known_to_exist);
87 copy_to_fd (from, tofd);
88@@ -640,9 +645,12 @@ copy_file (char const *from, char const
89 void
90 append_to_file (char const *from, char const *to)
91 {
92+ int to_flags = O_WRONLY | O_APPEND | O_BINARY;
93 int tofd;
94
95- if ((tofd = safe_open (to, O_WRONLY | O_BINARY | O_APPEND, 0)) < 0)
96+ if (! follow_symlinks)
97+ to_flags |= O_NOFOLLOW;
98+ if ((tofd = safe_open (to, to_flags, 0)) < 0)
99 pfatal ("Can't reopen file %s", quotearg (to));
100 copy_to_fd (from, tofd);
101 if (close (tofd) != 0)