aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2013-01-17 21:12:08 -0800
committerPaul Eggert2013-01-17 21:12:08 -0800
commit6772211202c57f0dc96e5725f882a2fa4ee98d2d (patch)
tree7e2ca991fa357834552b26980ca392d6f982559e
parent0eb8768885fab926acfae16d2fae8d39a72d8f35 (diff)
downloademacs-6772211202c57f0dc96e5725f882a2fa4ee98d2d.tar.gz
emacs-6772211202c57f0dc96e5725f882a2fa4ee98d2d.zip
Close a race when statting and reading files.
* fileio.c (Finsert_file_contents): Use open+fstat, not stat+open. This avoids a race if the file is renamed between stat and open. This race is not the problem originally noted in Bug#13149; see <http://bugs.gnu.org/13149#73> and later messages in the thread.
-rw-r--r--src/ChangeLog8
-rw-r--r--src/fileio.c44
2 files changed, 21 insertions, 31 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c85e0a789ea..f53b9a70e97 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12013-01-17 Paul Eggert <eggert@cs.ucla.edu>
2
3 Close a race when statting and reading files (Bug#13149).
4 * fileio.c (Finsert_file_contents): Use open+fstat, not stat+open.
5 This avoids a race if the file is renamed between stat and open.
6 This race is not the problem originally noted in Bug#13149;
7 see <http://bugs.gnu.org/13149#73> and later messages in the thread.
8
12013-01-17 Dmitry Antipov <dmantipov@yandex.ru> 92013-01-17 Dmitry Antipov <dmantipov@yandex.ru>
2 10
3 * lisp.h (toplevel): Add comment about using Lisp_Save_Value 11 * lisp.h (toplevel): Add comment about using Lisp_Save_Value
diff --git a/src/fileio.c b/src/fileio.c
index 8d711e8e6bf..41b8ae388d1 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3492,7 +3492,6 @@ by calling `format-decode', which see. */)
3492 (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) 3492 (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace)
3493{ 3493{
3494 struct stat st; 3494 struct stat st;
3495 int file_status;
3496 EMACS_TIME mtime; 3495 EMACS_TIME mtime;
3497 int fd; 3496 int fd;
3498 ptrdiff_t inserted = 0; 3497 ptrdiff_t inserted = 0;
@@ -3554,26 +3553,9 @@ by calling `format-decode', which see. */)
3554 orig_filename = filename; 3553 orig_filename = filename;
3555 filename = ENCODE_FILE (filename); 3554 filename = ENCODE_FILE (filename);
3556 3555
3557 fd = -1; 3556 fd = emacs_open (SSDATA (filename), O_RDONLY, 0);
3558 3557 if (fd < 0)
3559#ifdef WINDOWSNT
3560 {
3561 Lisp_Object tem = Vw32_get_true_file_attributes;
3562
3563 /* Tell stat to use expensive method to get accurate info. */
3564 Vw32_get_true_file_attributes = Qt;
3565 file_status = stat (SSDATA (filename), &st);
3566 Vw32_get_true_file_attributes = tem;
3567 }
3568#else
3569 file_status = stat (SSDATA (filename), &st);
3570#endif /* WINDOWSNT */
3571
3572 if (file_status == 0)
3573 mtime = get_stat_mtime (&st);
3574 else
3575 { 3558 {
3576 badopen:
3577 save_errno = errno; 3559 save_errno = errno;
3578 if (NILP (visit)) 3560 if (NILP (visit))
3579 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); 3561 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
@@ -3585,6 +3567,17 @@ by calling `format-decode', which see. */)
3585 goto notfound; 3567 goto notfound;
3586 } 3568 }
3587 3569
3570 /* Replacement should preserve point as it preserves markers. */
3571 if (!NILP (replace))
3572 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3573
3574 record_unwind_protect (close_file_unwind, make_number (fd));
3575
3576 if (fstat (fd, &st) != 0)
3577 report_file_error ("Getting input file status",
3578 Fcons (orig_filename, Qnil));
3579 mtime = get_stat_mtime (&st);
3580
3588 /* This code will need to be changed in order to work on named 3581 /* This code will need to be changed in order to work on named
3589 pipes, and it's probably just not worth it. So we should at 3582 pipes, and it's probably just not worth it. So we should at
3590 least signal an error. */ 3583 least signal an error. */
@@ -3600,17 +3593,6 @@ by calling `format-decode', which see. */)
3600 build_string ("not a regular file"), orig_filename); 3593 build_string ("not a regular file"), orig_filename);
3601 } 3594 }
3602 3595
3603 if (fd < 0)
3604 if ((fd = emacs_open (SSDATA (filename), O_RDONLY, 0)) < 0)
3605 goto badopen;
3606
3607 /* Replacement should preserve point as it preserves markers. */
3608 if (!NILP (replace))
3609 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3610
3611 record_unwind_protect (close_file_unwind, make_number (fd));
3612
3613
3614 if (!NILP (visit)) 3596 if (!NILP (visit))
3615 { 3597 {
3616 if (!NILP (beg) || !NILP (end)) 3598 if (!NILP (beg) || !NILP (end))