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