From 999a6dab3ee1c8e77bb348ba2389e7aeb5c062b2 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 21 Feb 2018 10:42:48 +0100 Subject: 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). --- ChangeLog | 8 ++++++++ elf/cache.c | 10 +++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a56f1fa..25b8e12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2018-02-21 Florian Weimer + [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 + [BZ #22787] * include/caller.h: Remove file. * elf/dl-caller.c: Likewise. diff --git a/elf/cache.c b/elf/cache.c index c2c010f..e63979d 100644 --- a/elf/cache.c +++ b/elf/cache.c @@ -454,8 +454,7 @@ save_cache (const char *cache_name) error (EXIT_FAILURE, errno, _("Writing of cache data failed")); } - if (write (fd, strings, total_strlen) != (ssize_t) total_strlen - || close (fd)) + if (write (fd, strings, total_strlen) != (ssize_t) total_strlen) error (EXIT_FAILURE, errno, _("Writing of cache data failed")); /* 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, 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. */ if (rename (temp_name, cache_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) != (ssize_t) (file_entries_size + total_strlen) - || close (fd)) + || fdatasync (fd) != 0 + || close (fd) != 0) { unlink (temp_name); goto out_fail; -- cgit v1.1