[Rpm-maint] [rpm-software-management/rpm] Sort files before passing to file attribute dependency generators (PR #3786)

Chris Riches notifications at github.com
Thu Jun 5 10:15:23 UTC 2025


The fc->fahash map is constructed in parallel, and so ends up with non-deterministic ordering of files. Passing this unordered list through to file attribute dependency generators can therefore result in non-reproducible RPM builds.

In theory, a file attribute generator should only care about each individual file it is given, and so the order should not matter. However, some generators track state in-between files and so this property does not hold. Notably, the python3-rpm-generators in RHEL (ab)use this system to apply package-level dependencies that are based on the package name rather than the content of any particular file, and simply apply this to the first file that they see from a matching package. Therefore, different input file orderings will result in different files getting the dependency, and therefore different output RPMs.

To avoid this, sort the files before passing them to the generators. Since the fc->fn array is already sorted by filename, we just need to sort the list of indices into that array.

-----------------------

The patch directly proposed by this PR is unfortunately untested as I gave up trying to make RPM master build on RHEL 9. What I _have_ tested is the following hopefully equivalent patch for RPM 4.16 as used in RHEL 9:

```c
--- a/build/rpmfc.c
+++ b/build/rpmfc.c
@@ -1010,6 +1010,13 @@ static const struct applyDep_s applyDepTable[] = {
     { 0, 0, NULL },
 };

+static int compareInts(const void *a, const void *b)
+{
+    int ia = *((int*)a);
+    int ib = *((int*)b);
+    return ia > ib ? 1 : ia < ib ? -1 : 0;
+}
+
 static int applyAttr(rpmfc fc, int aix, const char *aname,
                        const struct exclreg_s *excl,
                        const struct applyDep_s *dep)
@@ -1032,6 +1043,8 @@ static int applyAttr(rpmfc fc, int aix, const char *aname,

        if (!rstreq(cmd, "")) {
            char *ns = rpmfcAttrMacro(aname, "namespace", NULL);
+           /* Sort for reproducibility - hashmap was constructed in parallel */
+           qsort(ixs, n, sizeof(*ixs), compareInts);
            for (int i = 0; i < n; i++) {
                if (rpmfcHelper(fc, ixs[i], excl, dep->type, dep->tag,
                                ns, cmd, callable))
```

I can confirm that this 4.16 patch solves the issue on 4.16.
You can view, comment on, or merge this pull request online at:

  https://github.com/rpm-software-management/rpm/pull/3786

-- Commit Summary --

  * Sort files before passing to file attribute dependency generators

-- File Changes --

    M build/rpmfc.cc (2)

-- Patch Links --

https://github.com/rpm-software-management/rpm/pull/3786.patch
https://github.com/rpm-software-management/rpm/pull/3786.diff

-- 
Reply to this email directly or view it on GitHub:
https://github.com/rpm-software-management/rpm/pull/3786
You are receiving this because you are subscribed to this thread.

Message ID: <rpm-software-management/rpm/pull/3786 at github.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20250605/4def62ba/attachment-0001.htm>


More information about the Rpm-maint mailing list