kittoku / Open-SSTP-Client

Open SSTP Client for Android
MIT License
402 stars 104 forks source link

Reproducible Builds #141

Open IzzySoft opened 2 months ago

IzzySoft commented 2 months ago

At IzzyOnDroid we support Reproducible Builds (see: Reproducible Builds, special client support and more at IzzyOnDroid). Trying for yours, I was able to successfully generate the APK using ./gradlew assembleRelease, but the resulting APKs were not identical. Was that APK really built from a clean tree at the commit the tag points to? If so, did I miss some build options? And if not, which commit was it? Here's the diff between the APK at tag v1.9.1 and the one we've built from the same tag:

  -rw-r--r--  0.0 unx       56 b-       52 defN 1981-01-01 01:01:02 05cd8676 META-INF/com/android/build/gradle/app-metadata.properties
- -rw-r--r--  0.0 unx     2465 b-     2465 stor 1981-01-01 01:01:02 daa30e84 assets/dexopt/baseline.prof
+ -rw-r--r--  0.0 unx     2464 b-     2464 stor 1981-01-01 01:01:02 d10c906e assets/dexopt/baseline.prof
  -rw-r--r--  0.0 unx      244 b-      244 stor 1981-01-01 01:01:02 2420eb05 assets/dexopt/baseline.profm
- -rw-r--r--  0.0 unx  9211376 b-  3389130 defN 1981-01-01 01:01:02 6cae058e classes.dex
+ -rw-r--r--  0.0 unx  9211368 b-  3389019 defN 1981-01-01 01:01:02 21d51ab4 classes.dex
  -rw-r--r--  0.0 unx     2372 b-      896 defN 1981-01-01 01:01:02 5440ae8f classes2.dex

The diff from the classes.dex suggests your version a.o. has an additional call (-|: iget-object v3, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;; maybe local changes not committed?):

 |: const/4 v5, #int 0 // #0
-|: packed-switch v1, 00000454 // +00000449
+|: packed-switch v1, 00000452 // +00000447
 |: new-instance v12, Ljava/lang/IllegalStateException;
 |: const-string v0, "call to 'resume' before 'invoke' with coroutine"
 |: invoke-direct {v12, v0}, Ljava/lang/IllegalStateException;.<init>:(Ljava/lang/String;)V
 |: throw v12
 |: invoke-static {v12}, Lkotlin/ResultKt;.throwOnFailure:(Ljava/lang/Object;)V
-|: goto/16 0440 // +0427
+|: goto/16 043e // +0425
 |: invoke-static {v12}, Lkotlin/ResultKt;.throwOnFailure:(Ljava/lang/Object;)V
 |: goto/16 03e8 // +03ca
 |: invoke-static {v12}, Lkotlin/ResultKt;.throwOnFailure:(Ljava/lang/Object;)V
@@ -1681403,7 +1681403,7 @@
 |: move-result-object v1
 |: invoke-static {v12, v1}, Lkotlin/jvm/internal/Intrinsics;.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z
 |: move-result v12
-|: if-eqz v12, 0443 // +0196
+|: if-eqz v12, 0441 // +0194
 |: new-instance v12, Lkittoku/osc/client/ppp/auth/EAPMSAuthClient;
 |: iget-object v1, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;
 |: invoke-virtual {v1}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge;
@@ -1681575,15 +1681575,14 @@
 |: invoke-static {v1, v12}, Lkittoku/osc/control/Controller;.access$setOutgoingManager$p:(Lkittoku/osc/control/Controller;Lkittoku/osc/io/OutgoingManager;)V
 |: iget-object v12, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;
 |: new-instance v1, Lkittoku/osc/control/NetworkObserver;
-|: iget-object v3, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;
-|: invoke-virtual {v3}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge;
+|: invoke-virtual {v12}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge;
 |: move-result-object v3
 |: invoke-direct {v1, v3}, Lkittoku/osc/control/NetworkObserver;.<init>:(Lkittoku/osc/SharedBridge;)V
 |: invoke-static {v12, v1}, Lkittoku/osc/control/Controller;.access$setObserver$p:(Lkittoku/osc/control/Controller;Lkittoku/osc/control/NetworkObserver;)V
 |: iget-object v12, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;
 |: invoke-static {v12}, Lkittoku/osc/control/Controller;.access$isReconnectionEnabled$p:(Lkittoku/osc/control/Controller;)Z
 |: move-result v12
-|: if-eqz v12, 042e // +0012
+|: if-eqz v12, 042c // +0012
 |: iget-object v12, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;
 |: invoke-virtual {v12}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge;
 |: move-result-object v12
@@ -1681599,7 +1681598,7 @@
 |: iput v3, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.label:I
 |: invoke-static {v12, v1, v5, v2}, Lkittoku/osc/control/Controller;.access$expectProceeded:(Lkittoku/osc/control/Controller;Lkittoku/osc/Where;Ljava/lang/Long;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
 |: move-result-object v12
-|: if-ne v12, v0, 0440 // +0003
+|: if-ne v12, v0, 043e // +0003
 |: return-object v0
 |: sget-object v12, Lkotlin/Unit;.INSTANCE:Lkotlin/Unit;
 |: return-object v12
@@ -1681616,8 +1681615,8 @@
       catches       : (none)
       positions     :
       locals        :
-        0x0000 - 0x047a reg=11 this Lkittoku/osc/control/Controller$launchJobMain$1;
-        0x0000 - 0x047a reg=12 (null) Ljava/lang/Object;
+        0x0000 - 0x0478 reg=11 this Lkittoku/osc/control/Controller$launchJobMain$1;
+        0x0000 - 0x0478 reg=12 (null) Ljava/lang/Object;

We'd appreciate if you could help making your build reproducible. We've prepared some hints on reproducible builds for that.

Looking forward to your reply!

cc @obfusk

kittoku commented 2 months ago

I just cleaned the project and rebuild an apk, but the same classes.dex was produced.

Could you try re-pull or re-clone the repository? Maybe my git rebase caused something bad.

IzzySoft commented 2 months ago

I can of course retry, but I see no new commit. We're building the commit the tag is pointing to, to compare the resulting APK to the one attached to it.

Might be some "flakyness" then, so let me try for that. OK, 10 runs now produced the same classes.dex (sha1sum: 2f8b921e441e1428e2a99051a00f702788ee3a4c) that did not match yours (sha1sum: 24177e4429f0c742bb3bac86191322bb10a268ab), so it's unlikely to be a "flaky build". You're sure you built from the commit the tag points to? No "local commit" you forgot to push? What SDK do you use? Any specifics in your build environment? I've built on Debian Bookworm with OpenJDK 17. And yes, the build always runs in a clean environment here, with a fresh pull (using a Podman container that's "abandoned" at the end of the process).

khashayarnazari commented 1 month ago

ok yes

در تاریخ دوشنبه ۹ سپتامبر ۲۰۲۴، ۱۵:۲۰ Izzy @.***> نوشت:

At IzzyOnDroid we support Reproducible Builds https://reproducible-builds.org/ (see: Reproducible Builds, special client support and more at IzzyOnDroid https://android.izzysoft.de/articles/named/iod-rbs-mirrors-clients). Trying for yours, I was able to successfully generate the APK using ./gradlew assembleRelease, but the resulting APKs were not identical. Was that APK really built from a clean tree at the commit the tag points to? If so, did I miss some build options? And if not, which commit was it? Here's the diff between the APK at tag v1.9.1 and the one we've built from the same tag:

-rw-r--r-- 0.0 unx 56 b- 52 defN 1981-01-01 01:01:02 05cd8676 META-INF/com/android/build/gradle/app-metadata.properties- -rw-r--r-- 0.0 unx 2465 b- 2465 stor 1981-01-01 01:01:02 daa30e84 assets/dexopt/baseline.prof+ -rw-r--r-- 0.0 unx 2464 b- 2464 stor 1981-01-01 01:01:02 d10c906e assets/dexopt/baseline.prof -rw-r--r-- 0.0 unx 244 b- 244 stor 1981-01-01 01:01:02 2420eb05 assets/dexopt/baseline.profm- -rw-r--r-- 0.0 unx 9211376 b- 3389130 defN 1981-01-01 01:01:02 6cae058e classes.dex+ -rw-r--r-- 0.0 unx 9211368 b- 3389019 defN 1981-01-01 01:01:02 21d51ab4 classes.dex -rw-r--r-- 0.0 unx 2372 b- 896 defN 1981-01-01 01:01:02 5440ae8f classes2.dex

The diff from the classes.dex suggests your version a.o. has an additional call (-|: iget-object v3, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;; maybe local changes not committed?):

|: const/4 v5, #int 0 // #0-|: packed-switch v1, 00000454 // +00000449+|: packed-switch v1, 00000452 // +00000447 |: new-instance v12, Ljava/lang/IllegalStateException; |: const-string v0, "call to 'resume' before 'invoke' with coroutine" |: invoke-direct {v12, v0}, Ljava/lang/IllegalStateException;.:(Ljava/lang/String;)V |: throw v12 |: invoke-static {v12}, Lkotlin/ResultKt;.throwOnFailure:(Ljava/lang/Object;)V-|: goto/16 0440 // +0427+|: goto/16 043e // +0425 |: invoke-static {v12}, Lkotlin/ResultKt;.throwOnFailure:(Ljava/lang/Object;)V |: goto/16 03e8 // +03ca |: invoke-static {v12}, Lkotlin/ResultKt;.throwOnFailure:(Ljava/lang/Object;)V@@ -1681403,7 +1681403,7 @@ |: move-result-object v1 |: invoke-static {v12, v1}, Lkotlin/jvm/internal/Intrinsics;.areEqual:(Ljava/lang/Object;Ljava/lang/Object;)Z |: move-result v12-|: if-eqz v12, 0443 // +0196+|: if-eqz v12, 0441 // +0194 |: new-instance v12, Lkittoku/osc/client/ppp/auth/EAPMSAuthClient; |: iget-object v1, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller; |: invoke-virtual {v1}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge;@@ -1681575,15 +1681575,14 @@ |: invoke-static {v1, v12}, Lkittoku/osc/control/Controller;.access$setOutgoingManager$p:(Lkittoku/osc/control/Controller;Lkittoku/osc/io/OutgoingManager;)V |: iget-object v12, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller; |: new-instance v1, Lkittoku/osc/control/NetworkObserver;-|: iget-object v3, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller;-|: invoke-virtual {v3}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge;+|: invoke-virtual {v12}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge; |: move-result-object v3 |: invoke-direct {v1, v3}, Lkittoku/osc/control/NetworkObserver;.:(Lkittoku/osc/SharedBridge;)V |: invoke-static {v12, v1}, Lkittoku/osc/control/Controller;.access$setObserver$p:(Lkittoku/osc/control/Controller;Lkittoku/osc/control/NetworkObserver;)V |: iget-object v12, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller; |: invoke-static {v12}, Lkittoku/osc/control/Controller;.access$isReconnectionEnabled$p:(Lkittoku/osc/control/Controller;)Z |: move-result v12-|: if-eqz v12, 042e // +0012+|: if-eqz v12, 042c // +0012 |: iget-object v12, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.this$0:Lkittoku/osc/control/Controller; |: invoke-virtual {v12}, Lkittoku/osc/control/Controller;.getBridge$app_release:()Lkittoku/osc/SharedBridge; |: move-result-object v12@@ -1681599,7 +1681598,7 @@ |: iput v3, v11, Lkittoku/osc/control/Controller$launchJobMain$1;.label:I |: invoke-static {v12, v1, v5, v2}, Lkittoku/osc/control/Controller;.access$expectProceeded:(Lkittoku/osc/control/Controller;Lkittoku/osc/Where;Ljava/lang/Long;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; |: move-result-object v12-|: if-ne v12, v0, 0440 // +0003+|: if-ne v12, v0, 043e // +0003 |: return-object v0 |: sget-object v12, Lkotlin/Unit;.INSTANCE:Lkotlin/Unit; |: return-object v12@@ -1681616,8 +1681615,8 @@ catches : (none) positions : locals :- 0x0000 - 0x047a reg=11 this Lkittoku/osc/control/Controller$launchJobMain$1;- 0x0000 - 0x047a reg=12 (null) Ljava/lang/Object;+ 0x0000 - 0x0478 reg=11 this Lkittoku/osc/control/Controller$launchJobMain$1;+ 0x0000 - 0x0478 reg=12 (null) Ljava/lang/Object;

We'd appreciate if you could help making your build reproducible. We've prepared some hints on reproducible builds https://gitlab.com/IzzyOnDroid/repo/-/wikis/Reproducible-Builds for that.

Looking forward to your reply!

cc @obfusk https://github.com/obfusk

— Reply to this email directly, view it on GitHub https://github.com/kittoku/Open-SSTP-Client/issues/141, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQGUEE5SKG4KBZB22KOWGS3ZVWDPVAVCNFSM6AAAAABN4LWBCKVHI2DSMVQWIX3LMV43ASLTON2WKOZSGUYTGNZUGEZDSNA . You are receiving this because you are subscribed to this thread.Message ID: @.***>