Status Update
Comments
sg...@google.com <sg...@google.com>
ma...@gmail.com <ma...@gmail.com> #2
We’ve shared this with our product and engineering teams and will continue to provide updates as more information becomes available.
sg...@google.com <sg...@google.com> #3
ma...@gmail.com <ma...@gmail.com> #4
We have looked into the feature request you have reported and would like to inform you that this is working as intended. We do not think such an option would be understandable by most users, so we don't think there is a strong case for offering this.
As for disabling connectivity checks :
- the VPN might be actually relying on the result of these connectivity checks (they are available through public APIs).
- the VPN may be a split tunnel, letting part of the traffic over the underlying network, or only affect a given set of apps. In both these cases, the connectivity checks are still necessary for smooth operation of all the legitimate traffic that doesn't go over the VPN.
- the connectivity checks are far from the only thing exempted from the VPN ; privileged apps can also bypass the VPN and this is necessary for their operation in many cases. An example is IWLAN, or tethering traffic.
- it's unclear to us what specific privacy impact is meant. The connectivity checks reveal there is an Android device at this address, which is plenty clear from the L2 connection and from the traffic going over the VPN anyway.
ma...@gmail.com <ma...@gmail.com> #5
Thanks for looking into this and responding to the feature request. We don't fully agree with your decision, and here is our feedback to your response:
We do not think such an option would be understandable by most users
We'd argue that "most users" would never see or understand "Always-on VPN" or "Block connections without VPN" neither. But they don't need to care, because it's deep down in menus they never visit. Out of set of users who do understand and use those two features, we believe that a large part are interested in preventing data leaks of all kinds.
the VPN might be actually relying on the result of these connectivity checks (they are available through public APIs).
Yes, true. But for users who only connect to WiFis without captive portals and don't care about the connectivity check, this traffic serves no purpose but to cause noise and leak metadata. We do understand that this would be a nuisance to most users whos' threat model does not include this type of leak. But we would prefer it if you could disable the connectivity check. Maybe upon connecting to a new WiFi there can be a button asking if the user would like to probe for captive portals, and the check is performed when that is clicked. Just like the notification users currently get when there is a captive portal, allowing them to open the portal, but happening before the check is performed.
the VPN may be a split tunnel, letting part of the traffic over the underlying network, or only affect a given set of apps. In both these cases, the connectivity checks are still necessary for smooth operation of all the legitimate traffic that doesn't go over the VPN.
Enabling split tunneling is opt-in, and connecting to WiFi with captive portals is also voluntary. We don't see why users who don't use either should be forced to leak this traffic on every WiFi connection.
the connectivity checks are far from the only thing exempted from the VPN ; privileged apps can also bypass the VPN and this is necessary for their operation in many cases. An example is IWLAN, or tethering traffic.
Yes, this is very sad. All of those should be possible to disable. Having tethering enabled is definitely opt-in, so not an issue really. But as a side note, I don't understand why Android does not send tethered traffic over the VPN, this is a security and usability concern for us and our users.
If there is a long list of things that Android leaks without the user's consent, that's even more relevant to our other issue then:
Is there a list of exactly what traffic goes outside the VPN available somewhere?
it's unclear to us what specific privacy impact is meant. The connectivity checks reveal there is an Android device at this address, which is plenty clear from the L2 connection and from the traffic going over the VPN anyway.
At L2, yes. But anything further away does not have access to the L2 data. For example my router can see that an Android device is connected, but anything beyond the router will only see the connectivity check. Let's take my ISP and home as an example. Only my router can see the Android device establishing a WiFi connection. But the ISP can now get a detailed log of when my phone connects, due to the connectivity check. Giving them pretty detailed information about when I come home. Since different versions of Android use different connection check domains, the leaked data is more fine grained than just "some Android device". Let's say I'm one of very few people in my area who uses a specific flavor of Android. A network provider carrying most internet traffic in the area could potentially observe me arriving at a cafe, work, home, gym or whatnot.
Why would it be clear from the traffic going over the VPN that the endpoint is an Android device? That traffic is encrypted. How would an observer on the network be able to differentiate between an Android, iOS or desktop device? Do you mean that the observer would figure it out from timings and packet sizes? That is fixable with for example injected noise.
sg...@google.com <sg...@google.com> #6
The following info doesn't solve the issue, but maybe someone will find it relevant.
Although connectivity checks can't be forced through the VPN, they can be customized or disabled. Special ROM support is not needed for this. More details here:
- To disable:
adb shell settings put global captive_portal_mode 0
- To undo:
adb shell settings delete global captive_portal_mode
This should work with just about any modern (or not-so-modern) Android ROM.
If Mullvad considers this a significant-enough leak, one possibility is that the Mullvad app could check the value of the global settings captive_portal_mode
and captive_portal_detection_enabled
(the deprecated option) and politely notify the user about this, maybe directing them to information and the impact and how to change it - or something to that effect.
ch...@google.com <ch...@google.com> #7
Thanks for the input! We tried that via Termux (which required root), so we were under the wrong impression that it would require root via adb as well. We'll continue to investigate how this might be useful for our users.
ch...@google.com <ch...@google.com> #8
You can ask your users to grant WRITE_SECURE_SETTINGS
adb shell "pm grant com.termux android.permission.WRITE_SECURE_SETTINGS"
or su -c "pm grant com.termux android.permission.WRITE_SECURE_SETTINGS"
(change package name) and then write the captive_portal_mode
setting with Settings.Global.putInt(context.getContentResolver(), "captive_portal_mode", 0)
. You can read the value without the permission with Settings.Global.getString(context.getContentResolver(), "captive_portal_mode")
.
Or ask users to directly set the value with root or adb. Termux provides adb
binary in android-tools
package and adb wireless mode can be used to get adb access directly on device without requiring a pc.
ch...@google.com <ch...@google.com> #9
ma...@gmail.com <ma...@gmail.com> #10
ch...@google.com <ch...@google.com> #11
Re-
ma...@gmail.com <ma...@gmail.com> #12
Hey! Any chance of re-opening this issue/feature request since it has gotten quite a lot of upvotes?
AOSP based GrapheneOS exposes this functionality in a separate settings screen under "Network & connectivity" -> "Internet connectivity checks" where the user can select one of the following:
- GrapheneOS server
- Standard (Google) server
- Off
Maybe something similar can be done in the AOSP?
ch...@google.com <ch...@google.com>
ap...@google.com <ap...@google.com> #13
Project: r8
Branch: 8.6
Author: Christoffer Adamsen <
Link:
Version 8.6.35
Expand for full commit details
Version 8.6.35
Bug: b/366932318
Change-Id: I8e18fd6469749d4e3bb478415d370a157f3a6aeb
Files:
- M
src/main/java/com/android/tools/r8/Version.java
Hash: 8eee0f0fceb7e2a40be3d0f4a5290881aa262ae3
Date: Wed Nov 20 10:38:52 2024
ap...@google.com <ap...@google.com> #14
Project: r8
Branch: 8.6
Author: Christoffer Adamsen <
Link:
Pin methods called from lambdas in argument propagation
Expand for full commit details
Pin methods called from lambdas in argument propagation
Bug: b/366932318
Change-Id: Ie3888ec6788637b897ecdde1027bb1b9aef99305
Files:
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: d24b82662e766abcbaeebc4002f66eee18526993
Date: Wed Nov 20 10:38:46 2024
ap...@google.com <ap...@google.com> #15
Project: r8
Branch: 8.7
Author: Christoffer Adamsen <
Link:
Pin methods called from lambdas in argument propagation
Expand for full commit details
Pin methods called from lambdas in argument propagation
Bug: b/366932318
Change-Id: Ie3888ec6788637b897ecdde1027bb1b9aef99305
Files:
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: fd2cff0120d88a4275e5e9a3812bb017cdcae533
Date: Wed Nov 20 10:38:49 2024
ap...@google.com <ap...@google.com> #16
Project: r8
Branch: 8.7
Author: Christoffer Adamsen <
Link:
Version 8.7.22
Expand for full commit details
Version 8.7.22
Bug: b/366932318
Change-Id: I1236e2692269bc0159f4cbf1070de19eb3784fee
Files:
- M
src/main/java/com/android/tools/r8/Version.java
Hash: 582ed883e44e204b76b9ecc4c9e6a8b570d6bb04
Date: Wed Nov 20 10:38:54 2024
ap...@google.com <ap...@google.com> #17
Project: r8
Branch: 8.8
Author: Christoffer Adamsen <
Link:
Pin methods called from lambdas in argument propagation
Expand for full commit details
Pin methods called from lambdas in argument propagation
Bug: b/366932318
Change-Id: Ie3888ec6788637b897ecdde1027bb1b9aef99305
Files:
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: cee68977713ba669f9099a8fb2412ad87afae93b
Date: Wed Nov 20 10:38:52 2024
ap...@google.com <ap...@google.com> #18
Project: r8
Branch: 8.8
Author: Christoffer Adamsen <
Link:
Version 8.8.19
Expand for full commit details
Version 8.8.19
Bug: b/366932318
Change-Id: I11fdec29da7b98ed3b822661231cd729b9276c83
Files:
- M
src/main/java/com/android/tools/r8/Version.java
Hash: 4650e0dbf088a5560f84d7a76b655757ebf85fa2
Date: Wed Nov 20 10:38:58 2024
ap...@google.com <ap...@google.com> #19
Project: r8
Branch: 8.6
Author: Christoffer Adamsen <
Link:
Pin methods called from lambdas in argument propagation
Expand for full commit details
Pin methods called from lambdas in argument propagation
Bug: b/366932318
Change-Id: Ie3888ec6788637b897ecdde1027bb1b9aef99305
Files:
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: d24b82662e766abcbaeebc4002f66eee18526993
Date: Wed Nov 20 10:38:46 2024
ap...@google.com <ap...@google.com> #20
Project: r8
Branch: 8.7
Author: Christoffer Adamsen <
Link:
Pin methods called from lambdas in argument propagation
Expand for full commit details
Pin methods called from lambdas in argument propagation
Bug: b/366932318
Change-Id: Ie3888ec6788637b897ecdde1027bb1b9aef99305
Files:
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: fd2cff0120d88a4275e5e9a3812bb017cdcae533
Date: Wed Nov 20 10:38:49 2024
ap...@google.com <ap...@google.com> #21
Project: r8
Branch: 8.5
Author: Christoffer Adamsen <
Link:
Pin methods called from lambdas in argument propagation
Expand for full commit details
Pin methods called from lambdas in argument propagation
Bug: b/366932318
Change-Id: Ie3888ec6788637b897ecdde1027bb1b9aef99305
Files:
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: f53bfc6bcde5ec53fa9489b9b77103ebe253bdc8
Date: Wed Nov 20 10:38:57 2024
ap...@google.com <ap...@google.com> #22
Project: r8
Branch: 8.5
Author: Christoffer Adamsen <
Link:
Version 8.5.47
Expand for full commit details
Version 8.5.47
Bug: b/366932318
Change-Id: Ib3884dfe3fcf4796a4c0c549e2fd2eaca21e8d8d
Files:
- M
src/main/java/com/android/tools/r8/Version.java
Hash: 4a9267032bd00ee006aabc896a002ab998b40835
Date: Wed Nov 20 10:39:03 2024
ma...@gmail.com <ma...@gmail.com> #23
Hi 👋
I finally had the time to test the fix using r8:8.8.19
but sadly it doesn't seem to fix my issue. I just rebased the use-r8
branch:
git clone https://github.com/apollographql/apollo-kotlin
cd apollo-kotlin
git checkout 6980cf48a4600b06042054d9e6bbf8f013e5e68d
./gradlew :apollo-gradle-plugin:testJava11 --rerun --tests '*operationIdGenerator is working*' --no-build-cache --no-configuration-cache
Still outputs the same:
Caused by: java.lang.AbstractMethodError: Receiver class com.apollographql.apollo.relocated.com.apollographql.apollo.ast.internal.Parser$$Lambda$1679/0x0000000800d5fc40 does not define or inherit an implementation of the resolved method 'abstract java.lang.Object invoke$3()' of interface com.apollographql.apollo.relocated.kotlin.jvm.functions.Function0.
at com.apollographql.apollo.relocated.com.apollographql.apollo.ast.internal.Parser.parseTopLevel(SourceFile:4)
at com.apollographql.apollo.relocated.com.apollographql.apollo.ast.internal.Parser.parseValue(SourceFile:1)
at com.apollographql.apollo.relocated.com.apollographql.apollo.ast.ApolloParser__ApiKt.parseAsGQLValue$lambda$7$ApolloParser__ApiKt(SourceFile:1)
Is there something I'm missing?
ma...@apollographql.com <ma...@apollographql.com> #24
Woops, bad commit, 8881b5481db7a66abcdabba7571fc7b72b3cf2dd
is the commit to use:
git clone https://github.com/apollographql/apollo-kotlin
cd apollo-kotlin
git checkout 8881b5481db7a66abcdabba7571fc7b72b3cf2dd
./gradlew :apollo-gradle-plugin:testJava11 --rerun --tests '*operationIdGenerator is working*' --no-build-cache --no-configuration-cache
ch...@google.com <ch...@google.com>
ap...@google.com <ap...@google.com> #25
Project: r8
Branch: main
Author: Christoffer Adamsen <
Link:
Account for lambda call sites in argument propagation
Expand for full commit details
Account for lambda call sites in argument propagation
Bug: b/366932318
Change-Id: I7d6378034d4bf7e607badbe266653e273fdcd14a
Files:
- M
src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: 887704078a06fc0090e7772c921a30602bf1a49f
Date: Wed Nov 20 06:09:06 2024
ch...@google.com <ch...@google.com> #26
Sorry about that. This should be fixed by
Can you check if the main version fixes your issue (jar is at
Running tests seems to work for me:
> Task :apollo-gradle-plugin:testJava11
OperationIdGeneratorTests > operationIdGenerator is working PASSED
ma...@gmail.com <ma...@gmail.com> #27
Works like a charm, thanks again!
ap...@google.com <ap...@google.com> #28
Project: r8
Branch: 8.5
Author: Christoffer Adamsen <
Link:
Version 8.5.48
Expand for full commit details
Version 8.5.48
Bug: b/366932318
Change-Id: Iddbe33a40bee481c66e67030690c704d69ce35b3
Files:
- M
src/main/java/com/android/tools/r8/Version.java
Hash: 06bef98a52ed82a92587f70f74de6e3ea4a660f1
Date: Mon Nov 25 20:21:04 2024
ap...@google.com <ap...@google.com> #29
Project: r8
Branch: 8.5
Author: Christoffer Adamsen <
Link:
Account for lambda call sites in argument propagation
Expand for full commit details
Account for lambda call sites in argument propagation
Bug: b/366932318
Change-Id: I7d6378034d4bf7e607badbe266653e273fdcd14a
Files:
- M
src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
- M
src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
Hash: 1f01e4cba3e840b5ba0647f53906b8f27ed477ac
Date: Mon Nov 25 20:20:58 2024
an...@google.com <an...@google.com> #30
Thank you for your patience while our engineering team worked to resolve this issue. A fix for this issue is now available in:
- Android Studio Ladybug Feature Drop | 2024.2.2 Patch 1
- Android Gradle Plugin 8.8.1
We encourage you to try the latest update.
If you notice further issues or have questions, please file a new bug report.
Thank you for taking the time to submit feedback — we really appreciate it!
Description
Hi!
I've just bumped into another edge case trying to relocate the Apollo Gradle Plugin jar with a recent version of R8.
Looks like some
invokedynamic
calls are not always rename.Sadly I haven't found a way to make a minimal reproducer but for the full reproducer, you can always try with this commit:https://github.com/apollographql/apollo-kotlin/commit/4aa521df0037eea13ba09b5dfe4a3c2746b28023
My understanding is that
kotlin.jvm.functions.Function0
was repackaged (so far so good) but also had its single abstract method renamed frominvoke
toinvoke$3
(this is the part I'm not sure how to reproduce without the full example). And the renaming was not taken into account in theinvokedynamic
callsite, leading to the exception above.Debugging has led me to ArgumentPropagatorMethodReprocessingEnqueuer.AffectedMethodUseRegistry , used to rewrite code after the argument propagation optimization has run.
I'm tempted to say
AffectedMethodUseRegistry
would need to implementregisterCallSite()
and callmarkAffected()
somewhere in there to rewrite the methods that contain callsites? Does that make any sense?