summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2018-02-21 10:42:48 +0100
committerFlorian Weimer <fweimer@redhat.com>2018-02-21 10:42:48 +0100
commit999a6dab3ee1c8e77bb348ba2389e7aeb5c062b2 (patch)
treeb88f28c02d2f98d8576f021b8d441814d848133b
parent52a01100ad011293197637e42b5be1a479a2f4ae (diff)
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).
-rw-r--r--ChangeLog8
-rw-r--r--elf/cache.c10
2 files changed, 15 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index a56f1fa0ff..25b8e1264d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
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>
+
[BZ #22787]
* include/caller.h: Remove file.
* elf/dl-caller.c: Likewise.
diff --git a/elf/cache.c b/elf/cache.c
index c2c010f97b..e63979da7d 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;