From: Michael Chang Date: Wed, 6 Dec 2023 03:42:04 +0000 (+0800) Subject: util/grub-mkstandalone: Ensure deterministic tar file creation by sorting contents X-Git-Tag: grub-2.12~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f18a899ab17169ab71fcf3919435c4b79495efcd;p=thirdparty%2Fgrub.git util/grub-mkstandalone: Ensure deterministic tar file creation by sorting contents 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 Signed-off-by: Bernhard Wiedemann Reviewed-by: Daniel Kiper --- diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c index 8e1229925..9009648e3 100644 --- a/util/grub-mkstandalone.c +++ b/util/grub-mkstandalone.c @@ -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; }