insecure tempfile problem

Yuuichi Teranishi teranisi @ gohome.org
2003年 5月 11日 (日) 18:26:22 JST


At Sat, 10 May 2003 11:37:21 +0900,
Yuuichi Teranishi wrote:
> 
> 対処方法はもうちょっと考えてみたいと思います。

* (Emacs 21 にはある) make-temp-file を、他の Emacsen 向けにも
  APEL あたりで用意するようにする。
* 上記 make-temp-file では、自分専用の一時ファイル置き場を
  確保してから一時ファイルを作るようにする。
* 一時ファイル生成は全般に make-temp-file を使う。

というのがいいのではないか、という気がしているのですが、
いかがでしょうか。

poe.el あたりに入れることを想定した make-temp-file の実装案を添付します。
temporary-file-directory が自分専用なら直下に一時ファイルを作り、そうで
なければ、直下に自分専用の一時ファイル置き場 (emacs-($USER)) を確保して、
一時ファイルを作ります。いちおう手元の XEmacs 21.4.12, Mule 2.3 @ 19.34
で動作確認してます。

Windows だとどうなるのか、さっぱりわからないので
どなたか詳しい方のフォローをいただきたいところです…。

-------------- next part --------------
;; Emacs 21. Create a temporary file. (lisp/subr.el)
(defvar temporary-file-directory-internal nil
  "A directory for a temporary file. Internal use only.")

(defun-maybe make-temp-file (prefix &optional dir-flag suffix)
  "Create a temporary file.
The returned file name (created by appending some random characters at the end
of PREFIX, and expand it against the temporary directory)
is guaranteed to point to a newly created empty file.
You can then use `write-region' to write new data into the file.

The temporary directory is `temporary-file-directory' if it is secure.
If not, `temporary-file-directory'/emacs-`user-login-name' is used.

If DIR-FLAG is non-nil, create a new empty directory instead of a file.
If SUFFIX is non-nil, add that at the end of the file name."
  ;; If `temporary-file-directory-internal' is nil,
  ;; (which means this is the first time to use this function)
  ;; set appropriate temporary directory.
  ;; (create a new temporal directory if necessary)
  (unless temporary-file-directory-internal
    (cond
     ((null temporary-file-directory)
      (error "`temporary-file-dirctory' is not set"))
     ((not (file-exists-p temporary-file-directory))
      (error "%s does not exist" temporary-file-directory))
     ((not (file-directory-p temporary-file-directory))
      (error "%s is not a directory" temporary-file-directory))
     ((not (file-writable-p temporary-file-directory))
      (error "%s is not writable" temporary-file-directory)))
    ;; If temporary-file-directory has right permission, use it.
    (if (and (eq (user-uid) (nth 2 (file-attributes
				    temporary-file-directory)))
	     ;; 448 is -rwx------
	     (eq (file-modes temporary-file-directory) 448))
	(setq temporary-file-directory-internal temporary-file-directory)
      ;; Use `temporary-file-directory'/emacs-`user-login-name'
      (let ((user-temp-dir (expand-file-name
			    (concat "emacs-" (user-login-name))
			    temporary-file-directory))
	    umask)
	(if (and (file-directory-p user-temp-dir)
		 (eq (user-uid) (nth 2 (file-attributes user-temp-dir)))
		 (eq (file-modes user-temp-dir) 448))
	    (setq temporary-file-directory-internal user-temp-dir)
	  (if (not (file-exists-p user-temp-dir))
	      (progn
		(setq umask (default-file-modes))
		(unwind-protect
		    (progn
		      (set-default-file-modes 448)
		      (make-directory user-temp-dir))
		  (set-default-file-modes umask))
		(setq temporary-file-directory-internal user-temp-dir))
	    (cond
	     ((and (file-exists-p user-temp-dir)
		   (not (file-directory-p user-temp-dir)))
	      (error "%s is not a directory"))
	     ((not (eq (user-uid) (nth 2 (file-attributes user-temp-dir))))
	      (error "%s is not owned by user"))
	     ((eq (file-modes user-temp-dir) 448)
	      (error "%s has incorrect permissions"))))))))
  (let ((umask (default-file-modes))
	file)
    (unwind-protect
	(progn
	  ;; 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.
	  (set-default-file-modes 448)
	  (while (condition-case ()
		     (progn
		       (setq file
			     (make-temp-name
			      (expand-file-name
			       prefix
			       temporary-file-directory-internal)))
		       (if suffix
			   (setq file (concat file suffix)))
		       (if dir-flag
			   (make-directory file)
			 ;; On Emacs 21, following line is:
			 ;; (write-region "" nil file nil 'silent nil 'excl)
			 (write-region "" nil file nil 'silent nil))
		       nil)
		   (file-already-exists t))
	    nil)
	  file)
      ;; Reset the umask.
      (set-default-file-modes umask))))
-------------- next part --------------
--
Yuuichi Teranishi (寺西裕一) <teranisi @ gohome.org>
GPG Public Key: http://www.gohome.org/gpg/teranisi.asc
"Only time will tell if I am right or I am wrong..."


More information about the Emacs-mime-ja mailing list