]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect-image: fix partition label version compare
authorLennart Poettering <lennart@poettering.net>
Fri, 2 Jun 2023 10:25:09 +0000 (12:25 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 2 Jun 2023 13:54:13 +0000 (15:54 +0200)
The logic was borked: if we find multiple partitions of the same
designator, we should first prefer the better arch, and then prefer the
better version, and then the first found. Fix that.

Fixes: #27897
src/shared/dissect-image.c

index becd13f4c5c6b4c10ac8faa82ab0f11e3c3c545e..cf432e2177ae5f24203c2f08b4a60c17d988cd3b 100644 (file)
@@ -1217,16 +1217,19 @@ static int dissect_image(
                                 }
 
                                 if (m->partitions[type.designator].found) {
+                                        int c;
+
                                         /* For most partition types the first one we see wins. Except for the
                                          * rootfs and /usr, where we do a version compare of the label, and
                                          * let the newest version win. This permits a simple A/B versioning
                                          * scheme in OS images. */
 
-                                        if (compare_arch(type.arch, m->partitions[type.designator].architecture) <= 0)
+                                        c = compare_arch(type.arch, m->partitions[type.designator].architecture);
+                                        if (c < 0) /* the arch we already found is better than the one we found now */
                                                 continue;
-
-                                        if (!partition_designator_is_versioned(type.designator) ||
-                                            strverscmp_improved(m->partitions[type.designator].label, label) >= 0)
+                                        if (c == 0 && /* same arch? then go by version in label */
+                                            (!partition_designator_is_versioned(type.designator) ||
+                                             strverscmp_improved(label, m->partitions[type.designator].label) <= 0))
                                                 continue;
 
                                         dissected_partition_done(m->partitions + type.designator);