diff options
| author | Paul Eggert | 2011-12-29 12:44:31 -0800 |
|---|---|---|
| committer | Paul Eggert | 2011-12-29 12:44:31 -0800 |
| commit | 09450bae84788f9645716e17006e222adf1dec7f (patch) | |
| tree | 09f5edb41135a2382c22449cd3177ffa78d441dd /src | |
| parent | 2cae5ba432fc30042950c073b7ec7807bb98bcde (diff) | |
| download | emacs-09450bae84788f9645716e17006e222adf1dec7f.tar.gz emacs-09450bae84788f9645716e17006e222adf1dec7f.zip | |
emacs: fix an auto-save permissions race condition
* fileio.c (auto_saving_dir_umask): New static var.
(Fmake_directory_internal): Use it.
(do_auto_save_make_dir): Set it, instead of invoking chmod after
creating the directory. The old code temporarily assigns
too-generous permissions to the directory.
(do_auto_save_eh): Clear it.
(Fdo_auto_save): Catch all errrors, not just file errors, so
that the var is always cleared.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/fileio.c | 17 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index f10e2955164..6c0185b7386 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2011-12-29 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | emacs: fix an auto-save permissions race condition | ||
| 4 | * fileio.c (auto_saving_dir_umask): New static var. | ||
| 5 | (Fmake_directory_internal): Use it. | ||
| 6 | (do_auto_save_make_dir): Set it, instead of invoking chmod after | ||
| 7 | creating the directory. The old code temporarily assigns | ||
| 8 | too-generous permissions to the directory. | ||
| 9 | (do_auto_save_eh): Clear it. | ||
| 10 | (Fdo_auto_save): Catch all errrors, not just file errors, so | ||
| 11 | that the var is always cleared. | ||
| 12 | |||
| 1 | 2011-12-28 Kenichi Handa <handa@m17n.org> | 13 | 2011-12-28 Kenichi Handa <handa@m17n.org> |
| 2 | 14 | ||
| 3 | * coding.c (Fdefine_coding_system_internal): Make an utf-8 base | 15 | * coding.c (Fdefine_coding_system_internal): Make an utf-8 base |
diff --git a/src/fileio.c b/src/fileio.c index 3306085491e..27ae8b82204 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -90,6 +90,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 90 | /* Nonzero during writing of auto-save files */ | 90 | /* Nonzero during writing of auto-save files */ |
| 91 | static int auto_saving; | 91 | static int auto_saving; |
| 92 | 92 | ||
| 93 | /* Nonzero umask during creation of auto-save directories */ | ||
| 94 | static int auto_saving_dir_umask; | ||
| 95 | |||
| 93 | /* Set by auto_save_1 to mode of original file so Fwrite_region will create | 96 | /* Set by auto_save_1 to mode of original file so Fwrite_region will create |
| 94 | a new file with the same mode as the original */ | 97 | a new file with the same mode as the original */ |
| 95 | static int auto_save_mode_bits; | 98 | static int auto_save_mode_bits; |
| @@ -2062,7 +2065,7 @@ DEFUN ("make-directory-internal", Fmake_directory_internal, | |||
| 2062 | #ifdef WINDOWSNT | 2065 | #ifdef WINDOWSNT |
| 2063 | if (mkdir (dir) != 0) | 2066 | if (mkdir (dir) != 0) |
| 2064 | #else | 2067 | #else |
| 2065 | if (mkdir (dir, 0777) != 0) | 2068 | if (mkdir (dir, 0777 & ~auto_saving_dir_umask) != 0) |
| 2066 | #endif | 2069 | #endif |
| 2067 | report_file_error ("Creating directory", list1 (directory)); | 2070 | report_file_error ("Creating directory", list1 (directory)); |
| 2068 | 2071 | ||
| @@ -5205,16 +5208,18 @@ do_auto_save_unwind_1 (Lisp_Object value) /* used as unwind-protect function */ | |||
| 5205 | static Lisp_Object | 5208 | static Lisp_Object |
| 5206 | do_auto_save_make_dir (Lisp_Object dir) | 5209 | do_auto_save_make_dir (Lisp_Object dir) |
| 5207 | { | 5210 | { |
| 5208 | Lisp_Object mode; | 5211 | Lisp_Object result; |
| 5209 | 5212 | ||
| 5210 | call2 (Qmake_directory, dir, Qt); | 5213 | auto_saving_dir_umask = 077; |
| 5211 | XSETFASTINT (mode, 0700); | 5214 | result = call2 (Qmake_directory, dir, Qt); |
| 5212 | return Fset_file_modes (dir, mode); | 5215 | auto_saving_dir_umask = 0; |
| 5216 | return result; | ||
| 5213 | } | 5217 | } |
| 5214 | 5218 | ||
| 5215 | static Lisp_Object | 5219 | static Lisp_Object |
| 5216 | do_auto_save_eh (Lisp_Object ignore) | 5220 | do_auto_save_eh (Lisp_Object ignore) |
| 5217 | { | 5221 | { |
| 5222 | auto_saving_dir_umask = 0; | ||
| 5218 | return Qnil; | 5223 | return Qnil; |
| 5219 | } | 5224 | } |
| 5220 | 5225 | ||
| @@ -5282,7 +5287,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) | |||
| 5282 | dir = Ffile_name_directory (listfile); | 5287 | dir = Ffile_name_directory (listfile); |
| 5283 | if (NILP (Ffile_directory_p (dir))) | 5288 | if (NILP (Ffile_directory_p (dir))) |
| 5284 | internal_condition_case_1 (do_auto_save_make_dir, | 5289 | internal_condition_case_1 (do_auto_save_make_dir, |
| 5285 | dir, Fcons (Fcons (Qfile_error, Qnil), Qnil), | 5290 | dir, Qt, |
| 5286 | do_auto_save_eh); | 5291 | do_auto_save_eh); |
| 5287 | UNGCPRO; | 5292 | UNGCPRO; |
| 5288 | } | 5293 | } |