From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Richard Stallman Newsgroups: gmane.emacs.devel Subject: Re: backup method Date: Tue, 01 Feb 2005 08:30:35 -0500 Message-ID: References: <20050127000210.GA6167@boetes.org> <200501270045.j0R0jIq06197@raven.dms.auburn.edu> <20050127015432.GB6167@boetes.org> <20050128035618.GI6167@boetes.org> <20050129060851.GQ6167@boetes.org> <200501291842.j0TIgVw09020@raven.dms.auburn.edu> <20050129225259.GT6167@boetes.org> <87r7k3zti5.fsf-monnier+emacs@gnu.org> <874qgyxw24.fsf-monnier+emacs@gnu.org> Reply-To: rms@gnu.org NNTP-Posting-Host: main.gmane.org X-Trace: sea.gmane.org 1107265771 20245 80.91.229.2 (1 Feb 2005 13:49:31 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 1 Feb 2005 13:49:31 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Feb 01 14:49:29 2005 Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1CvyMO-00017E-Kv for ged-emacs-devel@m.gmane.org; Tue, 01 Feb 2005 14:46:30 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1CvyZJ-00004z-2t for ged-emacs-devel@m.gmane.org; Tue, 01 Feb 2005 08:59:49 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1CvyWE-00076p-D2 for emacs-devel@gnu.org; Tue, 01 Feb 2005 08:56:38 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1CvyW4-0006vL-SN for emacs-devel@gnu.org; Tue, 01 Feb 2005 08:56:29 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1CvyVz-0006kx-UN for emacs-devel@gnu.org; Tue, 01 Feb 2005 08:56:23 -0500 Original-Received: from [199.232.76.164] (helo=fencepost.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.34) id 1Cvy9d-0005Sv-L5 for emacs-devel@gnu.org; Tue, 01 Feb 2005 08:33:17 -0500 Original-Received: from rms by fencepost.gnu.org with local (Exim 4.34) id 1Cvy71-0005le-Nd; Tue, 01 Feb 2005 08:30:36 -0500 Original-To: Stefan Monnier In-reply-to: <874qgyxw24.fsf-monnier+emacs@gnu.org> (message from Stefan Monnier on Sun, 30 Jan 2005 19:57:28 -0500) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org X-MailScanner-To: ged-emacs-devel@m.gmane.org Xref: main.gmane.org gmane.emacs.devel:32701 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:32701 - if backup-by-copying is t, then when writing the backup file we may follow a symlink (planted by some other user) to some important file. Simply writing a file in such a directory would raise the same issue, right? If so, it really has nothing to do with backups. I think the fix is to treat files in such directories as precious. Not because they really are precious, but because the handling of a precious file might avoid the problem. However, I think the existing code for basic-save-buffer-2 that handles file-precious-flag is not entirely correct for this. It tries to find a name that does not exist, but doesn't protect against the possibility that someone might create the name after it tests but before it uses the name. I wrote this patch to try to fix it. I also tried fixing backup-copy-buffer in a similar way, but isn't perfect; someone could delete the file and create a symlink in between the call to write-region and the call to copy-file. So we would need an "exclusive" option in copy-file too. *** files.el 28 Jan 2005 09:33:33 -0500 1.744 --- files.el 31 Jan 2005 08:33:15 -0500 *************** *** 3312,3350 **** ;; This requires write access to the containing dir, ;; which is why we don't try it if we don't have that access. (let ((realname buffer-file-name) ! tempname nogood i succeed (old-modtime (visited-file-modtime))) ! (setq i 0) ! (setq nogood t) ! ;; Find the temporary name to write under. ! (while nogood ! (setq tempname (format ! (if (and (eq system-type 'ms-dos) ! (not (msdos-long-file-names))) ! "%s#%d.tm#" ; MSDOS limits files to 8+3 ! (if (memq system-type '(vax-vms axp-vms)) ! "%s$tmp$%d" ! "%s#tmp#%d")) ! dir i)) ! (setq nogood (file-exists-p tempname)) ! (setq i (1+ i))) (unwind-protect ! (progn (clear-visited-file-modtime) ! (write-region (point-min) (point-max) ! tempname nil realname ! buffer-file-truename) ! (setq succeed t)) ! ;; If writing the temp file fails, ! ;; delete the temp file. ! (or succeed ! (progn ! (condition-case nil ! (delete-file tempname) ! (file-error nil)) ! (set-visited-file-modtime old-modtime)))) ! ;; Since we have created an entirely new file ! ;; and renamed it, make sure it gets the ! ;; right permission bits set. (setq setmodes (or setmodes (cons (file-modes buffer-file-name) buffer-file-name))) ;; We succeeded in writing the temp file, --- 3314,3354 ---- ;; This requires write access to the containing dir, ;; which is why we don't try it if we don't have that access. (let ((realname buffer-file-name) ! tempname succeed ! (umask (default-file-modes)) (old-modtime (visited-file-modtime))) ! ;; Create temp files with strict access rights. It's easy to ! ;; loosen them later, whereas it's impossible to close the ! ;; time-window of loose permissions otherwise. (unwind-protect ! (progn ! (clear-visited-file-modtime) ! (set-default-file-modes ?\700) ! ;; Try various temporary names. ! ;; This code follows the example of make-temp-file, ! ;; but it calls write-region in the appropriate way ! ;; for saving the buffer. ! (while (condition-case () ! (progn ! (setq tempname ! (make-temp-name ! (expand-file-name "tmp" dir))) ! (write-region (point-min) (point-max) ! tempname nil realname ! buffer-file-truename 'excl) ! nil) ! (file-already-exists t)) ! ;; The file was somehow created by someone else between ! ;; `make-temp-name' and `write-region', let's try again. ! nil) ! (setq succeed t)) ! ;; Reset the umask. ! (set-default-file-modes umask) ! ;; If we failed, restore the buffer's modtime. ! (unless succeed ! (set-visited-file-modtime old-modtime))) ! ;; Since we have created an entirely new file, ! ;; make sure it gets the right permission bits set. (setq setmodes (or setmodes (cons (file-modes buffer-file-name) buffer-file-name))) ;; We succeeded in writing the temp file,