aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/net
diff options
context:
space:
mode:
authorPaul Eggert2020-02-23 16:19:42 -0800
committerPaul Eggert2020-02-23 16:45:50 -0800
commit9d626dffc6ba62c0d7a1a5c712f576ed8684fd66 (patch)
tree6cc8fbe8e5bc02c3bb74139710814a0400e91a8a /lisp/net
parentc4ca8219dd6b8f06e67a0b767475b1259653b8e0 (diff)
downloademacs-9d626dffc6ba62c0d7a1a5c712f576ed8684fd66.tar.gz
emacs-9d626dffc6ba62c0d7a1a5c712f576ed8684fd66.zip
Add 'nofollow' flag to set-file-modes etc.
This avoids some race conditions (Bug#39683). E.g., if some other program changes a file to a symlink between the time Emacs creates the file and the time it changes the file’s permissions, using the new flag prevents Emacs from inadvertently changing the permissions of a victim in some completely unrelated directory. * admin/merge-gnulib (GNULIB_MODULES): Add fchmodat. * doc/lispref/files.texi (Testing Accessibility, Changing Files): * doc/lispref/os.texi (File Notifications): * etc/NEWS: Adjust documentation accordingly. * lib/chmodat.c, lib/fchmodat.c, lib/lchmod.c, m4/fchmodat.m4: * m4/lchmod.m4: New files, copied from Gnulib. * lib/gnulib.mk.in: Regenerate. * lisp/dired-aux.el (dired-do-chmod): * lisp/doc-view.el (doc-view-make-safe-dir): * lisp/emacs-lisp/autoload.el (autoload--save-buffer): * lisp/emacs-lisp/bytecomp.el (byte-compile-file): * lisp/eshell/em-pred.el (eshell-pred-file-mode): * lisp/files.el (backup-buffer-copy, copy-directory): * lisp/gnus/mail-source.el (mail-source-movemail): * lisp/gnus/mm-decode.el (mm-display-external): * lisp/gnus/nnmail.el (nnmail-write-region): * lisp/net/tramp-adb.el (tramp-adb-handle-file-local-copy) (tramp-adb-handle-write-region): * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-directly): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-write-region): * lisp/net/tramp.el (tramp-handle-write-region) (tramp-make-tramp-temp-file): * lisp/server.el (server-ensure-safe-dir): * lisp/url/url-util.el (url-make-private-file): When getting or setting file modes, avoid following symbolic links when the file is not supposed to be a symbolic link. * lisp/doc-view.el (doc-view-make-safe-dir): Omit no-longer-needed separate symlink test. * lisp/gnus/gnus-util.el (gnus-set-file-modes): * lisp/net/tramp.el (tramp-handle-file-modes): * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-modes): * src/fileio.c (symlink_nofollow_flag): New function. (Ffile_modes, Fset_file_modes): Support an optional FLAG arg. All C callers changed. * lisp/net/ange-ftp.el (ange-ftp-set-file-modes): * lisp/net/tramp-adb.el (tramp-adb-handle-set-file-modes): * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-modes): * lisp/net/tramp-smb.el (tramp-smb-handle-set-file-modes): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-modes): Accept an optional FLAG arg that is currently ignored, and add a FIXME comment for it. * m4/gnulib-comp.m4: Regenerate.
Diffstat (limited to 'lisp/net')
-rw-r--r--lisp/net/ange-ftp.el3
-rw-r--r--lisp/net/tramp-adb.el9
-rw-r--r--lisp/net/tramp-gvfs.el4
-rw-r--r--lisp/net/tramp-sh.el10
-rw-r--r--lisp/net/tramp-smb.el3
-rw-r--r--lisp/net/tramp-sudoedit.el6
-rw-r--r--lisp/net/tramp.el13
7 files changed, 30 insertions, 18 deletions
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index f28394260dd..e2d4d7dd057 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -4740,7 +4740,8 @@ NEWNAME should be the name to give the new compressed or uncompressed file.")
4740 (setq ange-ftp-ls-cache-file nil) ;Stop confusing Dired. 4740 (setq ange-ftp-ls-cache-file nil) ;Stop confusing Dired.
4741 0) 4741 0)
4742 4742
4743(defun ange-ftp-set-file-modes (filename mode) 4743(defun ange-ftp-set-file-modes (filename mode &optional flag)
4744 flag ;; FIXME: Support 'nofollow'.
4744 (ange-ftp-call-chmod (list (format "%o" mode) filename))) 4745 (ange-ftp-call-chmod (list (format "%o" mode) filename)))
4745 4746
4746(defun ange-ftp-make-symbolic-link (&rest _arguments) 4747(defun ange-ftp-make-symbolic-link (&rest _arguments)
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index aa7fe147c20..96ef95dbe30 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -591,7 +591,8 @@ Emacs dired can't find files."
591 (ignore-errors (delete-file tmpfile)) 591 (ignore-errors (delete-file tmpfile))
592 (tramp-error 592 (tramp-error
593 v 'file-error "Cannot make local copy of file `%s'" filename)) 593 v 'file-error "Cannot make local copy of file `%s'" filename))
594 (set-file-modes tmpfile (logior (or (file-modes filename) 0) #o0400))) 594 (set-file-modes tmpfile (logior (or (file-modes filename) 0) #o0400)
595 'nofollow))
595 tmpfile))) 596 tmpfile)))
596 597
597(defun tramp-adb-handle-file-writable-p (filename) 598(defun tramp-adb-handle-file-writable-p (filename)
@@ -636,7 +637,8 @@ But handle the case, if the \"test\" command is not available."
636 (tmpfile (tramp-compat-make-temp-file filename))) 637 (tmpfile (tramp-compat-make-temp-file filename)))
637 (when (and append (file-exists-p filename)) 638 (when (and append (file-exists-p filename))
638 (copy-file filename tmpfile 'ok) 639 (copy-file filename tmpfile 'ok)
639 (set-file-modes tmpfile (logior (or (file-modes tmpfile) 0) #o0600))) 640 (set-file-modes tmpfile (logior (or (file-modes tmpfile) 0) #o0600)
641 'nofollow))
640 (tramp-run-real-handler 642 (tramp-run-real-handler
641 #'write-region (list start end tmpfile append 'no-message lockname)) 643 #'write-region (list start end tmpfile append 'no-message lockname))
642 (with-tramp-progress-reporter 644 (with-tramp-progress-reporter
@@ -665,8 +667,9 @@ But handle the case, if the \"test\" command is not available."
665 (tramp-message v 0 "Wrote %s" filename)) 667 (tramp-message v 0 "Wrote %s" filename))
666 (run-hooks 'tramp-handle-write-region-hook)))) 668 (run-hooks 'tramp-handle-write-region-hook))))
667 669
668(defun tramp-adb-handle-set-file-modes (filename mode) 670(defun tramp-adb-handle-set-file-modes (filename mode &optional flag)
669 "Like `set-file-modes' for Tramp files." 671 "Like `set-file-modes' for Tramp files."
672 flag ;; FIXME: Support 'nofollow'.
670 (with-parsed-tramp-file-name filename nil 673 (with-parsed-tramp-file-name filename nil
671 (tramp-flush-file-properties v localname) 674 (tramp-flush-file-properties v localname)
672 (tramp-adb-send-command-and-check v (format "chmod %o %s" mode localname)))) 675 (tramp-adb-send-command-and-check v (format "chmod %o %s" mode localname))))
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 762c4fe4b3b..79835804bc0 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -1562,12 +1562,12 @@ If FILE-SYSTEM is non-nil, return file system attributes."
1562 (tramp-run-real-handler 1562 (tramp-run-real-handler
1563 #'rename-file (list filename newname ok-if-already-exists)))) 1563 #'rename-file (list filename newname ok-if-already-exists))))
1564 1564
1565(defun tramp-gvfs-handle-set-file-modes (filename mode) 1565(defun tramp-gvfs-handle-set-file-modes (filename mode &optional flag)
1566 "Like `set-file-modes' for Tramp files." 1566 "Like `set-file-modes' for Tramp files."
1567 (with-parsed-tramp-file-name filename nil 1567 (with-parsed-tramp-file-name filename nil
1568 (tramp-flush-file-properties v localname) 1568 (tramp-flush-file-properties v localname)
1569 (tramp-gvfs-send-command 1569 (tramp-gvfs-send-command
1570 v "gvfs-set-attribute" "-t" "uint32" 1570 v "gvfs-set-attribute" (if flag "-nt" "-t") "uint32"
1571 (tramp-gvfs-url-file-name (tramp-make-tramp-file-name v)) 1571 (tramp-gvfs-url-file-name (tramp-make-tramp-file-name v))
1572 "unix::mode" (number-to-string mode)))) 1572 "unix::mode" (number-to-string mode))))
1573 1573
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 5a3abc31ea6..f31d3615884 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1478,10 +1478,11 @@ of."
1478 ;; only if that agrees with the buffer's record. 1478 ;; only if that agrees with the buffer's record.
1479 (t (tramp-compat-time-equal-p mt tramp-time-doesnt-exist))))))))) 1479 (t (tramp-compat-time-equal-p mt tramp-time-doesnt-exist)))))))))
1480 1480
1481(defun tramp-sh-handle-set-file-modes (filename mode) 1481(defun tramp-sh-handle-set-file-modes (filename mode &optional flag)
1482 "Like `set-file-modes' for Tramp files." 1482 "Like `set-file-modes' for Tramp files."
1483 (with-parsed-tramp-file-name filename nil 1483 (with-parsed-tramp-file-name filename nil
1484 (tramp-flush-file-properties v localname) 1484 (tramp-flush-file-properties v localname)
1485 flag ;; FIXME: Support 'nofollow'.
1485 ;; FIXME: extract the proper text from chmod's stderr. 1486 ;; FIXME: extract the proper text from chmod's stderr.
1486 (tramp-barf-unless-okay 1487 (tramp-barf-unless-okay
1487 v 1488 v
@@ -2279,7 +2280,7 @@ the uid and gid from FILENAME."
2279 ;; We must change the ownership as local user. 2280 ;; We must change the ownership as local user.
2280 ;; Since this does not work reliable, we also 2281 ;; Since this does not work reliable, we also
2281 ;; give read permissions. 2282 ;; give read permissions.
2282 (set-file-modes tmpfile #o0777) 2283 (set-file-modes tmpfile #o0777 'nofollow)
2283 (tramp-set-file-uid-gid 2284 (tramp-set-file-uid-gid
2284 tmpfile 2285 tmpfile
2285 (tramp-get-remote-uid v 'integer) 2286 (tramp-get-remote-uid v 'integer)
@@ -3221,7 +3222,8 @@ STDERR can also be a file name."
3221 (delete-file tmpfile2))))) 3222 (delete-file tmpfile2)))))
3222 3223
3223 ;; Set proper permissions. 3224 ;; Set proper permissions.
3224 (set-file-modes tmpfile (tramp-default-file-modes filename)) 3225 (set-file-modes tmpfile (tramp-default-file-modes filename)
3226 'nofollow)
3225 ;; Set local user ownership. 3227 ;; Set local user ownership.
3226 (tramp-set-file-uid-gid tmpfile)) 3228 (tramp-set-file-uid-gid tmpfile))
3227 3229
@@ -3320,7 +3322,7 @@ STDERR can also be a file name."
3320 ;; handles permissions. 3322 ;; handles permissions.
3321 ;; Ensure that it is still readable. 3323 ;; Ensure that it is still readable.
3322 (when modes 3324 (when modes
3323 (set-file-modes tmpfile (logior (or modes 0) #o0400))) 3325 (set-file-modes tmpfile (logior (or modes 0) #o0400) 'nofollow))
3324 3326
3325 ;; This is a bit lengthy due to the different methods 3327 ;; This is a bit lengthy due to the different methods
3326 ;; possible for file transfer. First, we check whether the 3328 ;; possible for file transfer. First, we check whether the
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index f02be394a7b..95505ea101f 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -1464,8 +1464,9 @@ component is used as the target of the symlink."
1464 (tramp-flush-connection-property v "process-name") 1464 (tramp-flush-connection-property v "process-name")
1465 (tramp-flush-connection-property v "process-buffer"))))))) 1465 (tramp-flush-connection-property v "process-buffer")))))))
1466 1466
1467(defun tramp-smb-handle-set-file-modes (filename mode) 1467(defun tramp-smb-handle-set-file-modes (filename mode &optional flag)
1468 "Like `set-file-modes' for Tramp files." 1468 "Like `set-file-modes' for Tramp files."
1469 flag ;; FIXME: Support 'nofollow'.
1469 (with-parsed-tramp-file-name filename nil 1470 (with-parsed-tramp-file-name filename nil
1470 (when (tramp-smb-get-cifs-capabilities v) 1471 (when (tramp-smb-get-cifs-capabilities v)
1471 (tramp-flush-file-properties v localname) 1472 (tramp-flush-file-properties v localname)
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index f258ad6b931..4654d633fab 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -463,8 +463,9 @@ the result will be a local, non-Tramp, file name."
463 (tramp-sudoedit-send-command 463 (tramp-sudoedit-send-command
464 v "test" "-r" (tramp-compat-file-name-unquote localname))))) 464 v "test" "-r" (tramp-compat-file-name-unquote localname)))))
465 465
466(defun tramp-sudoedit-handle-set-file-modes (filename mode) 466(defun tramp-sudoedit-handle-set-file-modes (filename mode &optional flag)
467 "Like `set-file-modes' for Tramp files." 467 "Like `set-file-modes' for Tramp files."
468 flag ;; FIXME: Support 'nofollow'.
468 (with-parsed-tramp-file-name filename nil 469 (with-parsed-tramp-file-name filename nil
469 (tramp-flush-file-properties v localname) 470 (tramp-flush-file-properties v localname)
470 (unless (tramp-sudoedit-send-command 471 (unless (tramp-sudoedit-send-command
@@ -735,7 +736,8 @@ ID-FORMAT valid values are `string' and `integer'."
735 (file-attributes filename 'integer)) 736 (file-attributes filename 'integer))
736 gid)) 737 gid))
737 (tramp-set-file-uid-gid filename uid gid)) 738 (tramp-set-file-uid-gid filename uid gid))
738 (set-file-modes filename modes))))) 739 (set-file-modes filename modes
740 (when (eq mustbenew 'excl) 'nofollow))))))
739 741
740 742
741;; Internal functions. 743;; Internal functions.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 409e1f7499a..64acaa95d47 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -3179,10 +3179,13 @@ User is always nil."
3179 (copy-file filename tmpfile 'ok-if-already-exists 'keep-time) 3179 (copy-file filename tmpfile 'ok-if-already-exists 'keep-time)
3180 tmpfile))) 3180 tmpfile)))
3181 3181
3182(defun tramp-handle-file-modes (filename) 3182(defun tramp-handle-file-modes (filename &optional flag)
3183 "Like `file-modes' for Tramp files." 3183 "Like `file-modes' for Tramp files."
3184 (when-let ((attrs (file-attributes (or (file-truename filename) filename)))) 3184 (when-let ((attrs (file-attributes filename)))
3185 (tramp-mode-string-to-int (tramp-compat-file-attribute-modes attrs)))) 3185 (let ((mode-string (tramp-compat-file-attribute-modes attrs)))
3186 (if (and (not flag) (eq ?l (aref mode-string 0)))
3187 (tramp-handle-file-modes (file-chase-links filename) 'nofollow)
3188 (tramp-mode-string-to-int mode-string)))))
3186 3189
3187;; Localname manipulation functions that grok Tramp localnames... 3190;; Localname manipulation functions that grok Tramp localnames...
3188(defun tramp-handle-file-name-as-directory (file) 3191(defun tramp-handle-file-name-as-directory (file)
@@ -3884,7 +3887,7 @@ of."
3884 ;; renamed to the backup file. This case `save-buffer' 3887 ;; renamed to the backup file. This case `save-buffer'
3885 ;; handles permissions. 3888 ;; handles permissions.
3886 ;; Ensure that it is still readable. 3889 ;; Ensure that it is still readable.
3887 (set-file-modes tmpfile (logior (or modes 0) #o0400)) 3890 (set-file-modes tmpfile (logior (or modes 0) #o0400) 'nofollow)
3888 ;; We say `no-message' here because we don't want the visited file 3891 ;; We say `no-message' here because we don't want the visited file
3889 ;; modtime data to be clobbered from the temp file. We call 3892 ;; modtime data to be clobbered from the temp file. We call
3890 ;; `set-visited-file-modtime' ourselves later on. 3893 ;; `set-visited-file-modtime' ourselves later on.
@@ -4664,7 +4667,7 @@ Return the local name of the temporary file."
4664 (setq result nil) 4667 (setq result nil)
4665 ;; This creates the file by side effect. 4668 ;; This creates the file by side effect.
4666 (set-file-times result) 4669 (set-file-times result)
4667 (set-file-modes result #o0700))) 4670 (set-file-modes result #o0700 'nofollow)))
4668 4671
4669 ;; Return the local part. 4672 ;; Return the local part.
4670 (tramp-file-local-name result))) 4673 (tramp-file-local-name result)))