Merge "Update permission check for offloadEngine registration" into main
This commit is contained in:
@@ -17,15 +17,18 @@
|
|||||||
package com.android.server;
|
package com.android.server;
|
||||||
|
|
||||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||||
|
import static android.Manifest.permission.NETWORK_STACK;
|
||||||
import static android.net.ConnectivityManager.NETID_UNSET;
|
import static android.net.ConnectivityManager.NETID_UNSET;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
|
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
||||||
import static android.net.nsd.NsdManager.MDNS_DISCOVERY_MANAGER_EVENT;
|
import static android.net.nsd.NsdManager.MDNS_DISCOVERY_MANAGER_EVENT;
|
||||||
import static android.net.nsd.NsdManager.MDNS_SERVICE_EVENT;
|
import static android.net.nsd.NsdManager.MDNS_SERVICE_EVENT;
|
||||||
import static android.net.nsd.NsdManager.RESOLVE_SERVICE_SUCCEEDED;
|
import static android.net.nsd.NsdManager.RESOLVE_SERVICE_SUCCEEDED;
|
||||||
import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
|
import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
|
||||||
|
|
||||||
import static com.android.modules.utils.build.SdkLevel.isAtLeastU;
|
import static com.android.modules.utils.build.SdkLevel.isAtLeastU;
|
||||||
|
import static com.android.networkstack.apishim.ConstantsShim.REGISTER_NSD_OFFLOAD_ENGINE;
|
||||||
import static com.android.server.connectivity.mdns.MdnsRecord.MAX_LABEL_LENGTH;
|
import static com.android.server.connectivity.mdns.MdnsRecord.MAX_LABEL_LENGTH;
|
||||||
import static com.android.server.connectivity.mdns.util.MdnsUtils.Clock;
|
import static com.android.server.connectivity.mdns.util.MdnsUtils.Clock;
|
||||||
|
|
||||||
@@ -75,6 +78,7 @@ import com.android.internal.util.IndentingPrintWriter;
|
|||||||
import com.android.internal.util.State;
|
import com.android.internal.util.State;
|
||||||
import com.android.internal.util.StateMachine;
|
import com.android.internal.util.StateMachine;
|
||||||
import com.android.metrics.NetworkNsdReportedMetrics;
|
import com.android.metrics.NetworkNsdReportedMetrics;
|
||||||
|
import com.android.modules.utils.build.SdkLevel;
|
||||||
import com.android.net.module.util.CollectionUtils;
|
import com.android.net.module.util.CollectionUtils;
|
||||||
import com.android.net.module.util.DeviceConfigUtils;
|
import com.android.net.module.util.DeviceConfigUtils;
|
||||||
import com.android.net.module.util.InetAddressUtils;
|
import com.android.net.module.util.InetAddressUtils;
|
||||||
@@ -2098,9 +2102,7 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
public void registerOffloadEngine(String ifaceName, IOffloadEngine cb,
|
public void registerOffloadEngine(String ifaceName, IOffloadEngine cb,
|
||||||
@OffloadEngine.OffloadCapability long offloadCapabilities,
|
@OffloadEngine.OffloadCapability long offloadCapabilities,
|
||||||
@OffloadEngine.OffloadType long offloadTypes) {
|
@OffloadEngine.OffloadType long offloadTypes) {
|
||||||
// TODO: Relax the permission because NETWORK_SETTINGS is a signature permission, and
|
checkOffloadEnginePermission(mContext);
|
||||||
// it may not be possible for all the callers of this API to have it.
|
|
||||||
PermissionUtils.enforceNetworkStackPermissionOr(mContext, NETWORK_SETTINGS);
|
|
||||||
Objects.requireNonNull(ifaceName);
|
Objects.requireNonNull(ifaceName);
|
||||||
Objects.requireNonNull(cb);
|
Objects.requireNonNull(cb);
|
||||||
mNsdStateMachine.sendMessage(
|
mNsdStateMachine.sendMessage(
|
||||||
@@ -2111,13 +2113,31 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterOffloadEngine(IOffloadEngine cb) {
|
public void unregisterOffloadEngine(IOffloadEngine cb) {
|
||||||
// TODO: Relax the permission because NETWORK_SETTINGS is a signature permission, and
|
checkOffloadEnginePermission(mContext);
|
||||||
// it may not be possible for all the callers of this API to have it.
|
|
||||||
PermissionUtils.enforceNetworkStackPermissionOr(mContext, NETWORK_SETTINGS);
|
|
||||||
Objects.requireNonNull(cb);
|
Objects.requireNonNull(cb);
|
||||||
mNsdStateMachine.sendMessage(
|
mNsdStateMachine.sendMessage(
|
||||||
mNsdStateMachine.obtainMessage(NsdManager.UNREGISTER_OFFLOAD_ENGINE, cb));
|
mNsdStateMachine.obtainMessage(NsdManager.UNREGISTER_OFFLOAD_ENGINE, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkOffloadEnginePermission(Context context) {
|
||||||
|
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))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (PermissionUtils.checkAnyPermissionOf(context, NETWORK_STACK,
|
||||||
|
PERMISSION_MAINLINE_NETWORK_STACK, NETWORK_SETTINGS)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new SecurityException("Requires one of the following permissions: "
|
||||||
|
+ String.join(", ", List.of(REGISTER_NSD_OFFLOAD_ENGINE, NETWORK_STACK,
|
||||||
|
PERMISSION_MAINLINE_NETWORK_STACK, NETWORK_SETTINGS)) + ".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendNsdStateChangeBroadcast(boolean isEnabled) {
|
private void sendNsdStateChangeBroadcast(boolean isEnabled) {
|
||||||
|
|||||||
@@ -16,20 +16,27 @@
|
|||||||
|
|
||||||
package com.android.server;
|
package com.android.server;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||||
|
import static android.Manifest.permission.NETWORK_STACK;
|
||||||
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
|
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
|
||||||
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
|
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
|
||||||
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
|
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
|
||||||
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
|
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.InetAddresses.parseNumericAddress;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
|
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
||||||
import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_PLATFORM_MDNS_BACKEND;
|
import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_PLATFORM_MDNS_BACKEND;
|
||||||
import static android.net.connectivity.ConnectivityCompatChanges.RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS_T_AND_LATER;
|
import static android.net.connectivity.ConnectivityCompatChanges.RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS_T_AND_LATER;
|
||||||
import static android.net.nsd.NsdManager.FAILURE_BAD_PARAMETERS;
|
import static android.net.nsd.NsdManager.FAILURE_BAD_PARAMETERS;
|
||||||
import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
|
import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
|
||||||
import static android.net.nsd.NsdManager.FAILURE_OPERATION_NOT_RUNNING;
|
import static android.net.nsd.NsdManager.FAILURE_OPERATION_NOT_RUNNING;
|
||||||
|
|
||||||
|
import static com.android.networkstack.apishim.api33.ConstantsShim.REGISTER_NSD_OFFLOAD_ENGINE;
|
||||||
import static com.android.server.NsdService.DEFAULT_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF;
|
import static com.android.server.NsdService.DEFAULT_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF;
|
||||||
import static com.android.server.NsdService.MdnsListener;
|
import static com.android.server.NsdService.MdnsListener;
|
||||||
import static com.android.server.NsdService.NO_TRANSACTION;
|
import static com.android.server.NsdService.NO_TRANSACTION;
|
||||||
@@ -68,6 +75,8 @@ import android.app.ActivityManager.OnUidImportanceListener;
|
|||||||
import android.compat.testing.PlatformCompatChangeRule;
|
import android.compat.testing.PlatformCompatChangeRule;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.PermissionInfo;
|
||||||
import android.net.INetd;
|
import android.net.INetd;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.mdns.aidl.DiscoveryInfo;
|
import android.net.mdns.aidl.DiscoveryInfo;
|
||||||
@@ -84,6 +93,7 @@ import android.net.nsd.NsdManager.RegistrationListener;
|
|||||||
import android.net.nsd.NsdManager.ResolveListener;
|
import android.net.nsd.NsdManager.ResolveListener;
|
||||||
import android.net.nsd.NsdManager.ServiceInfoCallback;
|
import android.net.nsd.NsdManager.ServiceInfoCallback;
|
||||||
import android.net.nsd.NsdServiceInfo;
|
import android.net.nsd.NsdServiceInfo;
|
||||||
|
import android.net.nsd.OffloadEngine;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -161,6 +171,7 @@ public class NsdServiceTest {
|
|||||||
@Rule
|
@Rule
|
||||||
public TestRule compatChangeRule = new PlatformCompatChangeRule();
|
public TestRule compatChangeRule = new PlatformCompatChangeRule();
|
||||||
@Mock Context mContext;
|
@Mock Context mContext;
|
||||||
|
@Mock PackageManager mPackageManager;
|
||||||
@Mock ContentResolver mResolver;
|
@Mock ContentResolver mResolver;
|
||||||
@Mock MDnsManager mMockMDnsM;
|
@Mock MDnsManager mMockMDnsM;
|
||||||
@Mock Dependencies mDeps;
|
@Mock Dependencies mDeps;
|
||||||
@@ -198,6 +209,7 @@ public class NsdServiceTest {
|
|||||||
mockService(mContext, MDnsManager.class, MDnsManager.MDNS_SERVICE, mMockMDnsM);
|
mockService(mContext, MDnsManager.class, MDnsManager.MDNS_SERVICE, mMockMDnsM);
|
||||||
mockService(mContext, WifiManager.class, Context.WIFI_SERVICE, mWifiManager);
|
mockService(mContext, WifiManager.class, Context.WIFI_SERVICE, mWifiManager);
|
||||||
mockService(mContext, ActivityManager.class, Context.ACTIVITY_SERVICE, mActivityManager);
|
mockService(mContext, ActivityManager.class, Context.ACTIVITY_SERVICE, mActivityManager);
|
||||||
|
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||||
if (mContext.getSystemService(MDnsManager.class) == null) {
|
if (mContext.getSystemService(MDnsManager.class) == null) {
|
||||||
// Test is using mockito-extended
|
// Test is using mockito-extended
|
||||||
doCallRealMethod().when(mContext).getSystemService(MDnsManager.class);
|
doCallRealMethod().when(mContext).getSystemService(MDnsManager.class);
|
||||||
@@ -1664,6 +1676,33 @@ public class NsdServiceTest {
|
|||||||
assertThrows(IllegalArgumentException.class, () -> new NsdManager(mContext, service));
|
assertThrows(IllegalArgumentException.class, () -> new NsdManager(mContext, service));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@EnableCompatChanges(ENABLE_PLATFORM_MDNS_BACKEND)
|
||||||
|
public void testRegisterOffloadEngine_checkPermission()
|
||||||
|
throws PackageManager.NameNotFoundException {
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// TODO: add checks to test the packageName other than android
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void waitForIdle() {
|
private void waitForIdle() {
|
||||||
HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
|
HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user