Skip to content

Commit 6ea366b

Browse files
lucaslinAndroid Build Coastguard Worker
authored andcommitted
Make sure that only the owner can call stopVpnProfile()
In stopVpnProfile(), it doesn't check if the caller's package name is the same as the given one, so any app has chance to stop the VPN profile of other apps. Bug: 191382886 Test: atest FrameworksNetTests CtsNetTestCases \ CtsHostsideNetworkTests:HostsideVpnTests Change-Id: Ib0a6e9ed191ff8c8bd55ce9902d894b6a339ace2 Merged-In: I254ffd1c08ec058d594b4ea55cbae5505f8497cc (cherry picked from commit f3072fcd46112bad7c5f6ddd4cc35d2c67f00d11)
1 parent b292b32 commit 6ea366b

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

services/core/java/com/android/server/ConnectivityService.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import android.content.Intent;
7474
import android.content.IntentFilter;
7575
import android.content.pm.PackageManager;
76+
import android.content.pm.PackageManager.NameNotFoundException;
7677
import android.content.res.Configuration;
7778
import android.database.ContentObserver;
7879
import android.net.CaptivePortal;
@@ -4607,6 +4608,25 @@ public void deleteVpnProfile(@NonNull String packageName) {
46074608
}
46084609
}
46094610

4611+
private int getAppUid(final String app, final int userId) {
4612+
final PackageManager pm = mContext.getPackageManager();
4613+
final long token = Binder.clearCallingIdentity();
4614+
try {
4615+
return pm.getPackageUidAsUser(app, userId);
4616+
} catch (NameNotFoundException e) {
4617+
return -1;
4618+
} finally {
4619+
Binder.restoreCallingIdentity(token);
4620+
}
4621+
}
4622+
4623+
private void verifyCallingUidAndPackage(String packageName, int callingUid) {
4624+
final int userId = UserHandle.getUserId(callingUid);
4625+
if (getAppUid(packageName, userId) != callingUid) {
4626+
throw new SecurityException(packageName + " does not belong to uid " + callingUid);
4627+
}
4628+
}
4629+
46104630
/**
46114631
* Starts the VPN based on the stored profile for the given package
46124632
*
@@ -4618,7 +4638,9 @@ public void deleteVpnProfile(@NonNull String packageName) {
46184638
*/
46194639
@Override
46204640
public void startVpnProfile(@NonNull String packageName) {
4621-
final int user = UserHandle.getUserId(Binder.getCallingUid());
4641+
final int callingUid = Binder.getCallingUid();
4642+
verifyCallingUidAndPackage(packageName, callingUid);
4643+
final int user = UserHandle.getUserId(callingUid);
46224644
synchronized (mVpns) {
46234645
throwIfLockdownEnabled();
46244646
mVpns.get(user).startVpnProfile(packageName, mKeyStore);
@@ -4635,7 +4657,9 @@ public void startVpnProfile(@NonNull String packageName) {
46354657
*/
46364658
@Override
46374659
public void stopVpnProfile(@NonNull String packageName) {
4638-
final int user = UserHandle.getUserId(Binder.getCallingUid());
4660+
final int callingUid = Binder.getCallingUid();
4661+
verifyCallingUidAndPackage(packageName, callingUid);
4662+
final int user = UserHandle.getUserId(callingUid);
46394663
synchronized (mVpns) {
46404664
mVpns.get(user).stopVpnProfile(packageName);
46414665
}

tests/net/java/com/android/server/ConnectivityServiceTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,9 @@ public void setUp() throws Exception {
12241224
Arrays.asList(new UserInfo[] {
12251225
new UserInfo(VPN_USER, "", 0),
12261226
}));
1227+
final int userId = UserHandle.getCallingUserId();
1228+
final UserInfo primaryUser = new UserInfo(userId, "", UserInfo.FLAG_PRIMARY);
1229+
doReturn(primaryUser).when(mUserManager).getUserInfo(eq(userId));
12271230
final ApplicationInfo applicationInfo = new ApplicationInfo();
12281231
applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
12291232
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
@@ -1368,6 +1371,9 @@ private void mockDefaultPackages() throws Exception {
13681371
buildPackageInfo(/* SYSTEM */ false, APP2_UID),
13691372
buildPackageInfo(/* SYSTEM */ false, VPN_UID)
13701373
}));
1374+
final int userId = UserHandle.getCallingUserId();
1375+
when(mPackageManager.getPackageUidAsUser(TEST_PACKAGE_NAME, userId))
1376+
.thenReturn(Process.myUid());
13711377
}
13721378

13731379
private void verifyActiveNetwork(int transport) {
@@ -7068,6 +7074,18 @@ public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception {
70687074
assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID);
70697075
}
70707076

7077+
@Test
7078+
public void testStartVpnProfileFromDiffPackage() throws Exception {
7079+
final String notMyVpnPkg = "com.not.my.vpn";
7080+
assertThrows(SecurityException.class, () -> mService.startVpnProfile(notMyVpnPkg));
7081+
}
7082+
7083+
@Test
7084+
public void testStopVpnProfileFromDiffPackage() throws Exception {
7085+
final String notMyVpnPkg = "com.not.my.vpn";
7086+
assertThrows(SecurityException.class, () -> mService.stopVpnProfile(notMyVpnPkg));
7087+
}
7088+
70717089
@Test
70727090
public void testUidUpdateChangesInterfaceFilteringRule() throws Exception {
70737091
LinkProperties lp = new LinkProperties();

0 commit comments

Comments
 (0)