booster icon indicating copy to clipboard operation
booster copied to clipboard

Undeterministic booster.alias causes different initramfs when it should be equal

Open lucas-mior opened this issue 2 months ago • 7 comments

booster build booster.img
booster build booster2.img

diff booster.img booster2.img  # they are different even though nothing has changed in the system

booster unpack booster.img bunpack
booster unpack booster2.img bunpack2

git diff bunpack bunpack2

The diff shows that the only difference is the file usr/lib/modules/booster.alias. Sorting them makes the two images equal. Is there a reason for that? I would like to be able to just diff them to check if they match or not.

lucas-mior avatar Oct 18 '25 21:10 lucas-mior

Is there a reason for that?

I suspect it might be the alias ordering that leads to different outputs.

But it is better to verify it. Could you please run diffoscope tool and check what exactly the difference between these two files?

anatol avatar Oct 20 '25 03:10 anatol

I am 100% sure that the only difference between them is the ordering. So I think my solution is to post-process the initramfs. Could you give me a hint on how to repack the initramfs after unpacking and changing a file?

lucas-mior avatar Oct 21 '25 14:10 lucas-mior

It is still a good idea to verify the hypothesis using existing tooling like diffoscope.

As of the file sorting itself - the best option would be adding something like slices.Sort(aliases) right before writing the aliases array to the file here https://github.com/anatol/booster/blob/9bfe45c2383cfffc382f73b8bbec9cf5da82e3cb/generator/generator.go#L228

anatol avatar Oct 21 '25 18:10 anatol

@lucas-mior please see the content of the branch issue-309. Could you please check the fix and let me know if it works for you.

anatol avatar Nov 15 '25 20:11 anatol

Hey, thanks for taking the time. I have build the generator binary (after checking out issue-309) using go build from the generator dir. Unfortunately, the problem still persists. I have noticed that you included a sorting of the modules alias list. Building two images as I describe in the issue still results in different images.

Also I noted that my git diff command was wrong in the opening comment. To show the output below I run git diff --no-index bunpack1 bunpack2 (--no-index was missing).

diff --git a/bunpack1/usr/lib/modules/booster.alias b/bunpack2/usr/lib/modules/booster.alias
index 269386c..425235a 100644
--- a/bunpack1/usr/lib/modules/booster.alias
+++ b/bunpack2/usr/lib/modules/booster.alias
@@ -1,9 +1,9 @@
 acpi*:PNP0303:* i8042
 acpi*:PNP0C50:* i2c_hid_acpi
-cpu:type:x86,ven*fam*mod*:feature:*0081* crct10dif_pclmul
 cpu:type:x86,ven*fam*mod*:feature:*0081* ghash_clmulni_intel
-cpu:type:x86,ven*fam*mod*:feature:*0081* crc32_pclmul
+cpu:type:x86,ven*fam*mod*:feature:*0081* crct10dif_pclmul
 cpu:type:x86,ven*fam*mod*:feature:*0081* polyval_clmulni
+cpu:type:x86,ven*fam*mod*:feature:*0081* crc32_pclmul
 cpu:type:x86,ven*fam*mod*:feature:*0089* sha512_ssse3
 cpu:type:x86,ven*fam*mod*:feature:*0089* sha256_ssse3
 cpu:type:x86,ven*fam*mod*:feature:*0089* sha1_ssse3
@@ -12,24 +12,24 @@ cpu:type:x86,ven*fam*mod*:feature:*0099* aesni_intel
 cpu:type:x86,ven*fam*mod*:feature:*009C* sha1_ssse3
 cpu:type:x86,ven*fam*mod*:feature:*009C* sha512_ssse3
 cpu:type:x86,ven*fam*mod*:feature:*009C* sha256_ssse3
+cpu:type:x86,ven*fam*mod*:feature:*0125* sha256_ssse3
 cpu:type:x86,ven*fam*mod*:feature:*0125* sha1_ssse3
 cpu:type:x86,ven*fam*mod*:feature:*0125* sha512_ssse3
-cpu:type:x86,ven*fam*mod*:feature:*0125* sha256_ssse3
-cpu:type:x86,ven*fam*mod*:feature:*013D* sha1_ssse3
 cpu:type:x86,ven*fam*mod*:feature:*013D* sha256_ssse3
+cpu:type:x86,ven*fam*mod*:feature:*013D* sha1_ssse3
 crypto_842 842
 crypto_842_generic 842
 crypto_adiantum adiantum
-crypto_aegis128 aegis128
 crypto_aegis128 aegis128_aesni
+crypto_aegis128 aegis128
 crypto_aegis128_aesni aegis128_aesni
 crypto_aegis128_generic aegis128
 crypto_aegis128_simd aegis128
-crypto_aes padlock_aes
 crypto_aes aesni_intel
+crypto_aes padlock_aes
 crypto_ansi_cprng ansi_cprng
-crypto_aria aria_gfni_avx512_x86_64
 crypto_aria aria_aesni_avx2_x86_64
+crypto_aria aria_gfni_avx512_x86_64
 crypto_aria aria_aesni_avx_x86_64
 crypto_aria aria_generic
 crypto_aria_aesni_avx aria_aesni_avx_x86_64
@@ -50,10 +50,10 @@ crypto_blowfish blowfish_x86_64
 crypto_blowfish blowfish_generic
 crypto_blowfish_asm blowfish_x86_64
 crypto_blowfish_generic blowfish_generic
-crypto_camellia camellia_x86_64
-crypto_camellia camellia_aesni_avx_x86_64
 crypto_camellia camellia_generic
 crypto_camellia camellia_aesni_avx2
+crypto_camellia camellia_x86_64
+crypto_camellia camellia_aesni_avx_x86_64
 crypto_camellia_asm camellia_x86_64
 crypto_camellia_asm camellia_aesni_avx_x86_64
 crypto_camellia_asm camellia_aesni_avx2
@@ -75,20 +75,20 @@ crypto_chacha20_simd chacha_x86_64
 crypto_cipher_null crypto_null
 crypto_cmac cmac
 crypto_compress_null crypto_null
-crypto_crc32 crc32_generic
 crypto_crc32 crc32_pclmul
+crypto_crc32 crc32_generic
 crypto_crc32_generic crc32_generic
 crypto_crc32_pclmul crc32_pclmul
-crypto_crc32c crc32c_intel
 crypto_crc32c crc32c_generic
+crypto_crc32c crc32c_intel
 crypto_crc32c_generic crc32c_generic
 crypto_crc32c_intel crc32c_intel
 crypto_crct10dif crct10dif_pclmul
 crypto_crct10dif_pclmul crct10dif_pclmul
 crypto_cryptd cryptd
 crypto_cts cts
-crypto_curve25519 curve25519_generic
 crypto_curve25519 curve25519_x86_64
+crypto_curve25519 curve25519_generic
 crypto_curve25519_generic curve25519_generic
 crypto_curve25519_x86 curve25519_x86_64
 crypto_deflate deflate
@@ -130,8 +130,8 @@ crypto_poly1305 poly1305_x86_64
 crypto_poly1305 poly1305_generic
 crypto_poly1305_generic poly1305_generic
 crypto_poly1305_simd poly1305_x86_64
-crypto_polyval polyval_generic
 crypto_polyval polyval_clmulni
+crypto_polyval polyval_generic
 crypto_polyval_clmulni polyval_clmulni
 crypto_polyval_generic polyval_generic
 crypto_rfc4106 gcm
@@ -141,10 +141,10 @@ crypto_rfc7539 chacha20poly1305
 crypto_rfc7539esp chacha20poly1305
 crypto_rmd160 rmd160
 crypto_seqiv seqiv
-crypto_serpent serpent_generic
-crypto_serpent serpent_sse2_x86_64
-crypto_serpent serpent_avx2
 crypto_serpent serpent_avx_x86_64
+crypto_serpent serpent_avx2
+crypto_serpent serpent_sse2_x86_64
+crypto_serpent serpent_generic
 crypto_serpent_asm serpent_avx2
 crypto_serpent_generic serpent_generic
 crypto_sha1 sha1_ssse3
@@ -178,9 +178,9 @@ crypto_sm3 sm3_generic
 crypto_sm3 sm3_avx_x86_64
 crypto_sm3_avx sm3_avx_x86_64
 crypto_sm3_generic sm3_generic
+crypto_sm4 sm4_aesni_avx2_x86_64
 crypto_sm4 sm4_generic
 crypto_sm4 sm4_aesni_avx_x86_64
-crypto_sm4 sm4_aesni_avx2_x86_64
 crypto_sm4_aesni_avx sm4_aesni_avx_x86_64
 crypto_sm4_aesni_avx2 sm4_aesni_avx2_x86_64
 crypto_sm4_generic sm4_generic
@@ -189,10 +189,10 @@ crypto_streebog256 streebog_generic
 crypto_streebog256_generic streebog_generic
 crypto_streebog512 streebog_generic
 crypto_streebog512_generic streebog_generic
-crypto_twofish twofish_x86_64_3way
 crypto_twofish twofish_x86_64
-crypto_twofish twofish_avx_x86_64
 crypto_twofish twofish_generic
+crypto_twofish twofish_avx_x86_64
+crypto_twofish twofish_x86_64_3way
 crypto_twofish_asm twofish_x86_64_3way
 crypto_twofish_asm twofish_x86_64
 crypto_twofish_generic twofish_generic
@@ -201,8 +201,8 @@ crypto_wp256 wp512
 crypto_wp384 wp512
 crypto_wp512 wp512
 crypto_xcbc xcbc
-crypto_xchacha12 chacha_x86_64
 crypto_xchacha12 chacha_generic
+crypto_xchacha12 chacha_x86_64
 crypto_xchacha12_generic chacha_generic
 crypto_xchacha12_simd chacha_x86_64
 crypto_xchacha20 chacha_generic

lucas-mior avatar Nov 15 '25 23:11 lucas-mior

Thank you for the information @lucas-mior. I made additional changes to the fix.

Could you please try to pull the branch and try it one more time?

anatol avatar Nov 16 '25 00:11 anatol

Now running diff <image.img> <other.img> still reports different files, while git diff --no-index reports they are equal.

And you were right, diffoscope shows that the file content differs in the order of the modules files (as recorded in the zstd metadata).

~I suspect that this is caused by go unpackModule(modName) in kmod.go (non deterministic threads?).~ It seems that just calling unpackModule(modName) without a go routine produces a more consistent result, but it is still undeterministic.

lucas-mior avatar Nov 17 '25 13:11 lucas-mior