Skip to content

Commit

Permalink
Better support VPN lockdown mode on Android 13+
Browse files Browse the repository at this point in the history
Fixes #565.
  • Loading branch information
Mygod committed May 5, 2024
1 parent f9f8850 commit 1b803ef
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
* (since API 30) `Landroid/net/TetheringManager$TetheringEventCallback;->onTetherableInterfaceRegexpsChanged(Landroid/net/TetheringManager$TetheringInterfaceRegexps;)V,blocked`
* (since API 31) `Landroid/net/TetheringManager$TetheringEventCallback;->onSupportedTetheringTypes(Ljava/util/Set;)V,blocked`
* (since API 33) `Landroid/net/connectivity/android/net/BpfNetMapsConstants;->IIF_MATCH:J,blocked`
* (since API 33) `Landroid/net/connectivity/android/net/BpfNetMapsConstants;->LOCKDOWN_VPN_MATCH:J,blocked`
* (since API 33) `Landroid/net/connectivity/android/net/UidOwnerValue;-><init>(IJ)V,blocked`
* (since API 33) `Landroid/net/connectivity/android/net/UidOwnerValue;->rule:J,blocked`
* (since API 33) `Landroid/net/connectivity/com/android/net/module/util/BpfMap;-><init>(Ljava/lang/String;ILjava/lang/Class;Ljava/lang/Class;)V,blocked`
Expand Down Expand Up @@ -205,6 +206,7 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
* (since API 33) `Lcom/android/server/BpfNetMaps;->native_init()V`
* (since API 33) `Lcom/android/server/BpfNetMaps;->native_init(Z)V`
* (since API 33) `Lcom/android/server/BpfNetMaps;->native_removeUidInterfaceRules([I)I`
* (since API 33) `Lcom/android/server/BpfNetMaps;->native_updateUidLockdownRule(IZ)I`
* (since API 33) `Lcom/android/server/BpfNetMaps;->sInitialized:Z`
* (since API 30) `Lcom/android/server/SystemServer;->TETHERING_CONNECTOR_CLASS:Ljava/lang/String;`
* `Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V,unsupported`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,16 @@ data class RemoveUidInterfaceRuleCommand(private val uid: Int) : RootCommand<Par
private val newS32 by lazy { S32.getDeclaredConstructor(Int::class.java) }
private val newUidOwnerValue by lazy { UidOwnerValue.getDeclaredConstructor(Int::class.java, Long::class.java) }
private val ruleUidOwnerValue by lazy { UidOwnerValue.getDeclaredField("rule") }
private val iifMatch by lazy {
findConnectivityClass("android.net.BpfNetMapsConstants").getDeclaredField("IIF_MATCH").getLong(null)
private val matches by lazy {
try {
val constants = findConnectivityClass("android.net.BpfNetMapsConstants")
constants.getDeclaredField("IIF_MATCH").getLong(null) or
constants.getDeclaredField("LOCKDOWN_VPN_MATCH").getLong(null)
} catch (e: ReflectiveOperationException) {
Timber.w(e)
// https://android.googlesource.com/platform/packages/modules/Connectivity/+/android-13.0.0_r1/bpf_progs/bpf_shared.h#160
3 shl 7
}
}

private val deleteEntry by lazy { BpfMap.getDeclaredMethod("deleteEntry", Struct) }
Expand All @@ -88,10 +96,10 @@ data class RemoveUidInterfaceRuleCommand(private val uid: Int) : RootCommand<Par
val uidS32 = newS32.newInstance(uid)
val oldRule = ruleUidOwnerValue.getLong(value(uidOwnerMap, uidS32) ?: return false)
return when {
oldRule and iifMatch == 0L -> false
oldRule == iifMatch -> deleteEntry(uidOwnerMap, uidS32) as Boolean
oldRule and matches == 0L -> false
oldRule == matches -> deleteEntry(uidOwnerMap, uidS32) as Boolean
else -> true.also {
updateEntry(uidOwnerMap, uidS32, newUidOwnerValue.newInstance(0, oldRule and iifMatch.inv()))
updateEntry(uidOwnerMap, uidS32, newUidOwnerValue.newInstance(0, oldRule and matches.inv()))
}
}
}
Expand Down Expand Up @@ -131,9 +139,15 @@ data class RemoveUidInterfaceRuleCommand(private val uid: Int) : RootCommand<Par
BpfNetMaps.getDeclaredMethod("native_removeUidInterfaceRules", IntArray::class.java)
.apply { isAccessible = true }
}
private val updateUidLockdownRule by lazy {
BpfNetMaps.getDeclaredMethod("native_updateUidLockdownRule", Int::class.java, Boolean::class.java)
.apply { isAccessible = true }
}
operator fun invoke(uid: Int) {
val ret = removeUidInterfaceRules(bpfNetMaps, intArrayOf(uid)) as Int
var ret = removeUidInterfaceRules(bpfNetMaps, intArrayOf(uid)) as Int
check(ret == 0) { "native_removeUidInterfaceRules returns $ret" }
ret = updateUidLockdownRule(bpfNetMaps, uid, false) as Int
check(ret == 0) { "native_updateUidLockdownRule returns $ret" }
}
}

Expand Down

0 comments on commit 1b803ef

Please sign in to comment.