diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a3fd60e9d3b09..004f84422b442 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -900,9 +900,17 @@ public final class NetworkCapabilities implements Parcelable {
*
For NetworkCapability instances being sent from ConnectivityService, this value MUST be
* reset to Process.INVALID_UID unless all the following conditions are met:
*
+ *
The caller is the network owner, AND one of the following sets of requirements is met:
+ *
*
- * - The destination app is the network owner
- *
- The destination app has the ACCESS_FINE_LOCATION permission granted
+ *
- The described Network is a VPN
+ *
+ *
+ * OR:
+ *
+ *
+ * - The calling app is the network owner
+ *
- The calling app has the ACCESS_FINE_LOCATION permission granted
*
- The user's location toggle is on
*
*
@@ -928,7 +936,16 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Retrieves the UID of the app that owns this network.
*
- * For user privacy reasons, this field will only be populated if:
+ *
For user privacy reasons, this field will only be populated if the following conditions
+ * are met:
+ *
+ *
The caller is the network owner, AND one of the following sets of requirements is met:
+ *
+ *
+ * - The described Network is a VPN
+ *
+ *
+ * OR:
*
*
* - The calling app is the network owner
@@ -936,8 +953,8 @@ public final class NetworkCapabilities implements Parcelable {
*
- The user's location toggle is on
*
*
- * Instances of NetworkCapabilities sent to apps without the appropriate permissions will
- * have this field cleared out.
+ * Instances of NetworkCapabilities sent to apps without the appropriate permissions will have
+ * this field cleared out.
*/
public int getOwnerUid() {
return mOwnerUid;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0b4ad72ee26de..7dc66b9cc58f5 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1698,6 +1698,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
return newNc;
}
+ // Allow VPNs to see ownership of their own VPN networks - not location sensitive.
+ if (nc.hasTransport(TRANSPORT_VPN)) {
+ // Owner UIDs already checked above. No need to re-check.
+ return newNc;
+ }
+
Binder.withCleanCallingIdentity(
() -> {
if (!mLocationPermissionChecker.checkLocationPermission(
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index e654af706fca6..1f85d1046523f 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1106,7 +1106,8 @@ public class Vpn {
NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;
- mNetworkCapabilities.setOwnerUid(Binder.getCallingUid());
+ mNetworkCapabilities.setOwnerUid(mOwnerUID);
+ mNetworkCapabilities.setAdministratorUids(new int[] {mOwnerUID});
mNetworkCapabilities.setUids(createUserAndRestrictedProfilesRanges(mUserHandle,
mConfig.allowedApplications, mConfig.disallowedApplications));
long token = Binder.clearCallingIdentity();