ldconfig: Sync temporary files to disk before renaming them [BZ #20890]

If the system crashes before the file data has been written to disk, the
file system recovery upon the next mount may restore a partially
rewritten temporary file under the non-temporary (final) name (after the
rename operation).
This commit is contained in:
Florian Weimer 2018-02-21 10:42:48 +01:00
parent 52a01100ad
commit 999a6dab3e
2 changed files with 15 additions and 3 deletions

View File

@ -1,3 +1,11 @@
2018-02-21 Florian Weimer <fweimer@redhat.com>
[BZ #20890]
* elf/cache.c (save_cache): Call fsync on temporary file before
renaming it.
(save_aux_cache): Call fdatasync on temporary file before renaming
it.
2018-02-21 Florian Weimer <fweimer@redhat.com> 2018-02-21 Florian Weimer <fweimer@redhat.com>
[BZ #22787] [BZ #22787]

View File

@ -454,8 +454,7 @@ save_cache (const char *cache_name)
error (EXIT_FAILURE, errno, _("Writing of cache data failed")); error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
} }
if (write (fd, strings, total_strlen) != (ssize_t) total_strlen if (write (fd, strings, total_strlen) != (ssize_t) total_strlen)
|| close (fd))
error (EXIT_FAILURE, errno, _("Writing of cache data failed")); error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
/* Make sure user can always read cache file */ /* Make sure user can always read cache file */
@ -464,6 +463,10 @@ save_cache (const char *cache_name)
_("Changing access rights of %s to %#o failed"), temp_name, _("Changing access rights of %s to %#o failed"), temp_name,
S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR); S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR);
/* Make sure that data is written to disk. */
if (fsync (fd) != 0 || close (fd) != 0)
error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
/* Move temporary to its final location. */ /* Move temporary to its final location. */
if (rename (temp_name, cache_name)) if (rename (temp_name, cache_name))
error (EXIT_FAILURE, errno, _("Renaming of %s to %s failed"), temp_name, error (EXIT_FAILURE, errno, _("Renaming of %s to %s failed"), temp_name,
@ -818,7 +821,8 @@ save_aux_cache (const char *aux_cache_name)
if (write (fd, file_entries, file_entries_size + total_strlen) if (write (fd, file_entries, file_entries_size + total_strlen)
!= (ssize_t) (file_entries_size + total_strlen) != (ssize_t) (file_entries_size + total_strlen)
|| close (fd)) || fdatasync (fd) != 0
|| close (fd) != 0)
{ {
unlink (temp_name); unlink (temp_name);
goto out_fail; goto out_fail;