]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
util/grub-mkstandalone: Ensure deterministic tar file creation by sorting contents
authorMichael Chang <mchang@suse.com>
Wed, 6 Dec 2023 03:42:04 +0000 (11:42 +0800)
committerDaniel Kiper <daniel.kiper@oracle.com>
Tue, 12 Dec 2023 14:47:08 +0000 (15:47 +0100)
The add_tar_files() function currently iterates through a directory's
content using readdir(), which doesn't guarantee a specific order. This
lack of deterministic behavior impacts reproducibility in the build process.

This commit resolves the issue by introducing sorting functionality.
The list retrieved by readdir() is now sorted alphabetically before
incorporation into the tar archive, ensuring consistent and predictable
file ordering within the archive.

On the occasion fix tfp memory leak.

Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Bernhard Wiedemann <bwiedemann@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
util/grub-mkstandalone.c

index 8e1229925eaa2e10ebeea1a2c17c75c9d559ebab..9009648e312f10d43886abcb46b2bb25880818be 100644 (file)
@@ -205,22 +205,43 @@ add_tar_file (const char *from,
     {
       grub_util_fd_dir_t d;
       grub_util_fd_dirent_t de;
+      char **from_files;
+      grub_size_t alloc = 8, used = 0;
+      grub_size_t i;
 
       d = grub_util_fd_opendir (from);
 
+      from_files = xmalloc (alloc * sizeof (*from_files));
       while ((de = grub_util_fd_readdir (d)))
        {
-         char *fp, *tfp;
          if (strcmp (de->d_name, ".") == 0)
            continue;
          if (strcmp (de->d_name, "..") == 0)
            continue;
-         fp = grub_util_path_concat (2, from, de->d_name);
-         tfp = xasprintf ("%s/%s", to, de->d_name);
+         if (alloc <= used)
+           {
+             alloc <<= 1;
+             from_files = xrealloc (from_files, alloc * sizeof (*from_files));
+           }
+         from_files[used++] = xstrdup (de->d_name);
+       }
+
+      qsort (from_files, used, sizeof (*from_files), grub_qsort_strcmp);
+
+      for (i = 0; i < used; i++)
+       {
+         char *fp, *tfp;
+
+         fp = grub_util_path_concat (2, from, from_files[i]);
+         tfp = xasprintf ("%s/%s", to, from_files[i]);
          add_tar_file (fp, tfp);
+         free (tfp);
          free (fp);
+         free (from_files[i]);
        }
+
       grub_util_fd_closedir (d);
+      free (from_files);
       free (tcn);
       return;
     }