Update registerOffloadEngine() permission check
Update registerOffloadEngine() permission check to check the DEVICE_POWER permission in U. This change is required to allow the android TV device to access the API in U because the REGISTER_NSD_OFFLOAD_ENGINE permission can not be backported. Bug: 313546516 Test: TH Change-Id: I84b80d102a34487ad54719a86eb525b319e2fd8b
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import static android.Manifest.permission.DEVICE_POWER;
|
||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||
import static android.Manifest.permission.NETWORK_STACK;
|
||||
import static android.net.ConnectivityManager.NETID_UNSET;
|
||||
@@ -2104,11 +2105,17 @@ public class NsdService extends INsdManager.Stub {
|
||||
if (!SdkLevel.isAtLeastT()) {
|
||||
throw new SecurityException("API is not available in before API level 33");
|
||||
}
|
||||
// REGISTER_NSD_OFFLOAD_ENGINE was only added to the SDK in V, but may
|
||||
// be back ported to older builds: accept it as long as it's signature-protected
|
||||
if (PermissionUtils.checkAnyPermissionOf(context, REGISTER_NSD_OFFLOAD_ENGINE)
|
||||
&& (SdkLevel.isAtLeastV() || PermissionUtils.isSystemSignaturePermission(
|
||||
context, REGISTER_NSD_OFFLOAD_ENGINE))) {
|
||||
|
||||
// REGISTER_NSD_OFFLOAD_ENGINE was only added to the SDK in V.
|
||||
if (SdkLevel.isAtLeastV() && PermissionUtils.checkAnyPermissionOf(context,
|
||||
REGISTER_NSD_OFFLOAD_ENGINE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// REGISTER_NSD_OFFLOAD_ENGINE cannot be backport to U. In U, check the DEVICE_POWER
|
||||
// permission instead.
|
||||
if (!SdkLevel.isAtLeastV() && SdkLevel.isAtLeastU()
|
||||
&& PermissionUtils.checkAnyPermissionOf(context, DEVICE_POWER)) {
|
||||
return;
|
||||
}
|
||||
if (PermissionUtils.checkAnyPermissionOf(context, NETWORK_STACK,
|
||||
|
||||
@@ -21,15 +21,12 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
|
||||
import static android.Manifest.permission.NETWORK_STACK;
|
||||
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.content.pm.PermissionInfo.PROTECTION_SIGNATURE;
|
||||
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.os.Binder;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -56,25 +53,6 @@ public final class PermissionUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the permission has system signature.
|
||||
*/
|
||||
public static boolean isSystemSignaturePermission(@NonNull Context context,
|
||||
@NonNull String permission) {
|
||||
try {
|
||||
PermissionInfo permissionInfo = context.getPackageManager().getPermissionInfo(
|
||||
permission, 0 /* flags */);
|
||||
if (permissionInfo == null) {
|
||||
return false;
|
||||
}
|
||||
return "android".equals(permissionInfo.packageName)
|
||||
&& permissionInfo.getProtection() == PROTECTION_SIGNATURE;
|
||||
} catch (PackageManager.NameNotFoundException ignored) {
|
||||
// Ignored the NameNotFoundException and return false
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the context has one of give permission that is allowed
|
||||
* for a particular process and user ID running in the system.
|
||||
|
||||
@@ -16,15 +16,12 @@
|
||||
|
||||
package com.android.net.module.util
|
||||
|
||||
import android.Manifest.permission.INTERNET
|
||||
import android.Manifest.permission.NETWORK_SETTINGS
|
||||
import android.Manifest.permission.NETWORK_STACK
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManager.PERMISSION_DENIED
|
||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||
import android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
|
||||
import android.os.Build
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.android.net.module.util.PermissionUtils.checkAnyPermissionOf
|
||||
@@ -144,27 +141,4 @@ class PermissionUtilsTest {
|
||||
Assert.fail("Exception should have not been thrown with system feature enabled")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
|
||||
fun testIsSystemSignaturePermission() {
|
||||
assertTrue(
|
||||
PermissionUtils.isSystemSignaturePermission(
|
||||
context,
|
||||
NETWORK_SETTINGS
|
||||
)
|
||||
)
|
||||
assertFalse(
|
||||
PermissionUtils
|
||||
.isSystemSignaturePermission(context, PERMISSION_MAINLINE_NETWORK_STACK)
|
||||
)
|
||||
assertFalse(
|
||||
PermissionUtils
|
||||
.isSystemSignaturePermission(context, "test_permission")
|
||||
)
|
||||
assertFalse(
|
||||
PermissionUtils
|
||||
.isSystemSignaturePermission(context, INTERNET)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import static android.Manifest.permission.DEVICE_POWER;
|
||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||
import static android.Manifest.permission.NETWORK_STACK;
|
||||
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
|
||||
@@ -24,7 +25,6 @@ import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
|
||||
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
|
||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.content.pm.PermissionInfo.PROTECTION_SIGNATURE;
|
||||
import static android.net.InetAddresses.parseNumericAddress;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||
@@ -75,7 +75,6 @@ import android.compat.testing.PlatformCompatChangeRule;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.net.INetd;
|
||||
import android.net.Network;
|
||||
import android.net.mdns.aidl.DiscoveryInfo;
|
||||
@@ -170,6 +169,8 @@ public class NsdServiceTest {
|
||||
|
||||
@Rule
|
||||
public TestRule compatChangeRule = new PlatformCompatChangeRule();
|
||||
@Rule
|
||||
public TestRule ignoreRule = new DevSdkIgnoreRule();
|
||||
@Mock Context mContext;
|
||||
@Mock PackageManager mPackageManager;
|
||||
@Mock ContentResolver mResolver;
|
||||
@@ -1697,8 +1698,8 @@ public class NsdServiceTest {
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges(ENABLE_PLATFORM_MDNS_BACKEND)
|
||||
public void testRegisterOffloadEngine_checkPermission()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
public void testRegisterOffloadEngine_checkPermission_V() {
|
||||
final NsdManager client = connectClient(mService);
|
||||
final OffloadEngine offloadEngine = mock(OffloadEngine.class);
|
||||
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(NETWORK_STACK);
|
||||
@@ -1708,17 +1709,41 @@ public class NsdServiceTest {
|
||||
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(
|
||||
REGISTER_NSD_OFFLOAD_ENGINE);
|
||||
|
||||
PermissionInfo permissionInfo = new PermissionInfo("");
|
||||
permissionInfo.packageName = "android";
|
||||
permissionInfo.protectionLevel = PROTECTION_SIGNATURE;
|
||||
doReturn(permissionInfo).when(mPackageManager).getPermissionInfo(
|
||||
REGISTER_NSD_OFFLOAD_ENGINE, 0);
|
||||
client.registerOffloadEngine("iface1", OffloadEngine.OFFLOAD_TYPE_REPLY,
|
||||
OffloadEngine.OFFLOAD_CAPABILITY_BYPASS_MULTICAST_LOCK,
|
||||
Runnable::run, offloadEngine);
|
||||
client.unregisterOffloadEngine(offloadEngine);
|
||||
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(
|
||||
REGISTER_NSD_OFFLOAD_ENGINE);
|
||||
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(DEVICE_POWER);
|
||||
assertThrows(SecurityException.class,
|
||||
() -> client.registerOffloadEngine("iface1", OffloadEngine.OFFLOAD_TYPE_REPLY,
|
||||
OffloadEngine.OFFLOAD_CAPABILITY_BYPASS_MULTICAST_LOCK, Runnable::run,
|
||||
offloadEngine));
|
||||
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(
|
||||
REGISTER_NSD_OFFLOAD_ENGINE);
|
||||
final OffloadEngine offloadEngine2 = mock(OffloadEngine.class);
|
||||
client.registerOffloadEngine("iface2", OffloadEngine.OFFLOAD_TYPE_REPLY,
|
||||
OffloadEngine.OFFLOAD_CAPABILITY_BYPASS_MULTICAST_LOCK, Runnable::run,
|
||||
offloadEngine2);
|
||||
client.unregisterOffloadEngine(offloadEngine2);
|
||||
}
|
||||
|
||||
// TODO: add checks to test the packageName other than android
|
||||
@Test
|
||||
@EnableCompatChanges(ENABLE_PLATFORM_MDNS_BACKEND)
|
||||
@DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||
public void testRegisterOffloadEngine_checkPermission_U() {
|
||||
final NsdManager client = connectClient(mService);
|
||||
final OffloadEngine offloadEngine = mock(OffloadEngine.class);
|
||||
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(NETWORK_STACK);
|
||||
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(
|
||||
PERMISSION_MAINLINE_NETWORK_STACK);
|
||||
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(NETWORK_SETTINGS);
|
||||
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(
|
||||
REGISTER_NSD_OFFLOAD_ENGINE);
|
||||
|
||||
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(DEVICE_POWER);
|
||||
client.registerOffloadEngine("iface2", OffloadEngine.OFFLOAD_TYPE_REPLY,
|
||||
OffloadEngine.OFFLOAD_CAPABILITY_BYPASS_MULTICAST_LOCK, Runnable::run,
|
||||
offloadEngine);
|
||||
client.unregisterOffloadEngine(offloadEngine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user