]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - elf/cache.c
Update copyright dates not handled by scripts/update-copyrights.
[thirdparty/glibc.git] / elf / cache.c
index 9a600ea53530a6f2ad89bfa321c3b20df2b5b581..b8e9e6ccc32eb7eeb77a4ff606565c5bf3235b7e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2003,2005,2006,2007 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999.
 
@@ -13,8 +13,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
 #include <error.h>
@@ -26,6 +25,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <sys/fcntl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -91,6 +91,35 @@ print_entry (const char *lib, int flag, unsigned int osversion,
       break;
     case FLAG_MIPS64_LIBN64:
       fputs (",64bit", stdout);
+      break;
+    case FLAG_X8664_LIBX32:
+      fputs (",x32", stdout);
+      break;
+    case FLAG_ARM_LIBHF:
+      fputs (",hard-float", stdout);
+      break;
+    case FLAG_AARCH64_LIB64:
+      fputs (",AArch64", stdout);
+      break;
+    /* Uses the ARM soft-float ABI.  */
+    case FLAG_ARM_LIBSF:
+      fputs (",soft-float", stdout);
+      break;
+    case FLAG_MIPS_LIB32_NAN2008:
+      fputs (",nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN32_NAN2008:
+      fputs (",N32,nan2008", stdout);
+      break;
+    case FLAG_MIPS64_LIBN64_NAN2008:
+      fputs (",64bit,nan2008", stdout);
+      break;
+    case FLAG_RISCV_FLOAT_ABI_SOFT:
+      fputs (",soft-float", stdout);
+      break;
+    case FLAG_RISCV_FLOAT_ABI_DOUBLE:
+      fputs (",double-float", stdout);
+      break;
     case 0:
       break;
     default:
@@ -170,6 +199,11 @@ print_cache (const char *cache_name)
     }
   else
     {
+      /* Check for corruption, avoiding overflow.  */
+      if ((cache_size - sizeof (struct cache_file)) / sizeof (struct file_entry)
+         < cache->nlibs)
+       error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
+
       size_t offset = ALIGN_CACHE (sizeof (struct cache_file)
                                   + (cache->nlibs
                                      * sizeof (struct file_entry)));
@@ -361,7 +395,7 @@ save_cache (const char *cache_name)
        {
          /* We could subtract file_entries_new_size from str_offset -
             not doing so makes the code easier, the string table
-            always begins at the beginning of the the new cache
+            always begins at the beginning of the new cache
             struct.  */
          file_entries_new->libs[idx_new].flags = entry->flags;
          file_entries_new->libs[idx_new].osversion = entry->osversion;
@@ -425,8 +459,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 */
@@ -435,6 +468,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,
@@ -675,8 +712,9 @@ load_aux_cache (const char *aux_cache_name)
   if (aux_cache == MAP_FAILED
       || aux_cache_size < sizeof (struct aux_cache_file)
       || memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1)
-      || aux_cache->nlibs < 0
-      || aux_cache->nlibs >= aux_cache_size)
+      || aux_cache_size != (sizeof(struct aux_cache_file) +
+                           aux_cache->nlibs * sizeof(struct aux_cache_file_entry) +
+                           aux_cache->len_strings))
     {
       close (fd);
       init_aux_cache ();
@@ -788,7 +826,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;
@@ -800,5 +839,6 @@ save_aux_cache (const char *aux_cache_name)
 
 out_fail:
   /* Free allocated memory.  */
+  free (temp_name);
   free (file_entries);
 }