Merge changes Ifd6be50a,I857e40c9,I1b9f4fde,Ib3b43cf2
* changes: Prevent native_init from starting TrafficController Remove libutils dependency from libservice-connectivity Merge libtraffic_controller_jni into libservice-connectivity [NETD-TC#15] Make ConnectivityService and PermissionMonitor calls BpfNetMaps on T
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import android.net.INetd;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
@@ -27,10 +29,19 @@ import android.util.Log;
|
||||
*/
|
||||
public class BpfNetMaps {
|
||||
private static final String TAG = "BpfNetMaps";
|
||||
private final INetd mNetd;
|
||||
// TODO: change USE_JNI to SdkLevel.isAtLeastT()
|
||||
private static final boolean USE_JNI = false;
|
||||
|
||||
static {
|
||||
System.loadLibrary("traffic_controller_jni");
|
||||
native_init();
|
||||
if (USE_JNI) {
|
||||
System.loadLibrary("traffic_controller_jni");
|
||||
native_init();
|
||||
}
|
||||
}
|
||||
|
||||
public BpfNetMaps(INetd netd) {
|
||||
mNetd = netd;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,6 +52,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void addNaughtyApp(final int uid) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.bandwidthAddNaughtyApp(uid);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_addNaughtyApp(uid);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(err, "Unable to add naughty app: "
|
||||
@@ -56,6 +75,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void removeNaughtyApp(final int uid) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.bandwidthRemoveNaughtyApp(uid);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_removeNaughtyApp(uid);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(err, "Unable to remove naughty app: "
|
||||
@@ -71,6 +98,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void addNiceApp(final int uid) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.bandwidthAddNiceApp(uid);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_addNiceApp(uid);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(err, "Unable to add nice app: "
|
||||
@@ -86,6 +121,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void removeNiceApp(final int uid) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.bandwidthRemoveNiceApp(uid);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_removeNiceApp(uid);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(err, "Unable to remove nice app: "
|
||||
@@ -102,6 +145,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void setChildChain(final int childChain, final boolean enable) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.firewallEnableChildChain(childChain, enable);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_setChildChain(childChain, enable);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(-err, "Unable to set child chain: "
|
||||
@@ -124,6 +175,14 @@ public class BpfNetMaps {
|
||||
*/
|
||||
public int replaceUidChain(final String chainName, final boolean isAllowlist,
|
||||
final int[] uids) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.firewallReplaceUidChain(chainName, isAllowlist, uids);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
final int err = native_replaceUidChain(chainName, isAllowlist, uids);
|
||||
if (err != 0) {
|
||||
Log.e(TAG, "replaceUidChain failed: " + Os.strerror(-err));
|
||||
@@ -140,8 +199,15 @@ public class BpfNetMaps {
|
||||
* @throws ServiceSpecificException in case of failure, with an error code indicating the
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void setUidRule(final int childChain, final int uid,
|
||||
final int firewallRule) {
|
||||
public void setUidRule(final int childChain, final int uid, final int firewallRule) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.firewallSetUidRule(childChain, uid, firewallRule);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_setUidRule(childChain, uid, firewallRule);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(-err, "Unable to set uid rule: "
|
||||
@@ -166,6 +232,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void addUidInterfaceRules(final String ifName, final int[] uids) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.firewallAddUidInterfaceRules(ifName, uids);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception when updating permissions: " + e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_addUidInterfaceRules(ifName, uids);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(err, "Unable to add uid interface rules: "
|
||||
@@ -184,6 +258,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void removeUidInterfaceRules(final int[] uids) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.firewallRemoveUidInterfaceRules(uids);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception when updating permissions: " + e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_removeUidInterfaceRules(uids);
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(err, "Unable to remove uid interface rules: "
|
||||
@@ -197,6 +279,14 @@ public class BpfNetMaps {
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void swapActiveStatsMap() {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.trafficSwapActiveStatsMap();
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int err = native_swapActiveStatsMap();
|
||||
if (err != 0) {
|
||||
throw new ServiceSpecificException(err, "Unable to swap active stats map: "
|
||||
@@ -213,8 +303,16 @@ public class BpfNetMaps {
|
||||
* revoke all permissions for the uids.
|
||||
* @param uids uid of users to grant permission
|
||||
*/
|
||||
public void setNetPermForUids(final int permission, final int[] uids) {
|
||||
native_setPermissionForUids(permission, uids);
|
||||
public void setNetPermForUids(final int permissions, final int[] uids) {
|
||||
if (!USE_JNI) {
|
||||
try {
|
||||
mNetd.trafficSetNetPermForUids(permissions, uids);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Pass appId list of special permission failed." + e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
native_setPermissionForUids(permissions, uids);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,7 +353,7 @@ public class BpfNetMaps {
|
||||
private native int native_addUidInterfaceRules(String ifName, int[] uids);
|
||||
private native int native_removeUidInterfaceRules(int[] uids);
|
||||
private native int native_swapActiveStatsMap();
|
||||
private native void native_setPermissionForUids(int permission, int[] uids);
|
||||
private native void native_setPermissionForUids(int permissions, int[] uids);
|
||||
private native int native_setCounterSet(int counterSet, int uid);
|
||||
private native int native_deleteTagData(int tag, int uid);
|
||||
}
|
||||
|
||||
@@ -397,6 +397,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private NetworkStatsManager mStatsManager;
|
||||
private NetworkPolicyManager mPolicyManager;
|
||||
private final NetdCallback mNetdCallback;
|
||||
private final BpfNetMaps mBpfNetMaps;
|
||||
|
||||
/**
|
||||
* TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
|
||||
@@ -1344,6 +1345,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name,
|
||||
TETHERING_MODULE_NAME, defaultEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BpfNetMaps implementation to use in ConnectivityService.
|
||||
* @param netd
|
||||
* @return BpfNetMaps implementation.
|
||||
*/
|
||||
public BpfNetMaps getBpfNetMaps(INetd netd) {
|
||||
return new BpfNetMaps(netd);
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectivityService(Context context) {
|
||||
@@ -1412,6 +1422,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
|
||||
|
||||
mNetd = netd;
|
||||
mBpfNetMaps = mDeps.getBpfNetMaps(netd);
|
||||
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
|
||||
mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
|
||||
@@ -1445,7 +1456,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
|
||||
mPermissionMonitor = new PermissionMonitor(mContext, mNetd, mBpfNetMaps);
|
||||
|
||||
mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
|
||||
// Listen for user add/removes to inform PermissionMonitor.
|
||||
@@ -10828,11 +10839,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
try {
|
||||
if (add) {
|
||||
mNetd.bandwidthAddNiceApp(uid);
|
||||
mBpfNetMaps.addNiceApp(uid);
|
||||
} else {
|
||||
mNetd.bandwidthRemoveNiceApp(uid);
|
||||
mBpfNetMaps.removeNiceApp(uid);
|
||||
}
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
@@ -10843,11 +10854,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
try {
|
||||
if (add) {
|
||||
mNetd.bandwidthAddNaughtyApp(uid);
|
||||
mBpfNetMaps.addNaughtyApp(uid);
|
||||
} else {
|
||||
mNetd.bandwidthRemoveNaughtyApp(uid);
|
||||
mBpfNetMaps.removeNaughtyApp(uid);
|
||||
}
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
@@ -10857,9 +10868,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
enforceNetworkStackOrSettingsPermission();
|
||||
|
||||
try {
|
||||
mNetd.firewallSetUidRule(chain, uid,
|
||||
mBpfNetMaps.setUidRule(chain, uid,
|
||||
allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
@@ -10869,8 +10880,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
enforceNetworkStackOrSettingsPermission();
|
||||
|
||||
try {
|
||||
mNetd.firewallEnableChildChain(chain, enable);
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
mBpfNetMaps.setChildChain(chain, enable);
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
@@ -10882,22 +10893,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
try {
|
||||
switch (chain) {
|
||||
case ConnectivityManager.FIREWALL_CHAIN_DOZABLE:
|
||||
mNetd.firewallReplaceUidChain("fw_dozable", true /* isAllowList */, uids);
|
||||
mBpfNetMaps.replaceUidChain("fw_dozable", true /* isAllowList */, uids);
|
||||
break;
|
||||
case ConnectivityManager.FIREWALL_CHAIN_STANDBY:
|
||||
mNetd.firewallReplaceUidChain("fw_standby", false /* isAllowList */, uids);
|
||||
mBpfNetMaps.replaceUidChain("fw_standby", false /* isAllowList */, uids);
|
||||
break;
|
||||
case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE:
|
||||
mNetd.firewallReplaceUidChain("fw_powersave", true /* isAllowList */, uids);
|
||||
mBpfNetMaps.replaceUidChain("fw_powersave", true /* isAllowList */, uids);
|
||||
break;
|
||||
case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED:
|
||||
mNetd.firewallReplaceUidChain("fw_restricted", true /* isAllowList */, uids);
|
||||
mBpfNetMaps.replaceUidChain("fw_restricted", true /* isAllowList */, uids);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("replaceFirewallChain with invalid chain: "
|
||||
+ chain);
|
||||
}
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
@@ -10906,8 +10917,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
public void swapActiveStatsMap() {
|
||||
enforceNetworkStackOrSettingsPermission();
|
||||
try {
|
||||
mNetd.trafficSwapActiveStatsMap();
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
mBpfNetMaps.swapActiveStatsMap();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.net.module.util.CollectionUtils;
|
||||
import com.android.server.BpfNetMaps;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -93,6 +94,7 @@ public class PermissionMonitor {
|
||||
private final INetd mNetd;
|
||||
private final Dependencies mDeps;
|
||||
private final Context mContext;
|
||||
private final BpfNetMaps mBpfNetMaps;
|
||||
|
||||
@GuardedBy("this")
|
||||
private final Set<UserHandle> mUsers = new HashSet<>();
|
||||
@@ -184,12 +186,14 @@ public class PermissionMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) {
|
||||
this(context, netd, new Dependencies());
|
||||
public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd,
|
||||
@NonNull final BpfNetMaps bpfNetMaps) {
|
||||
this(context, netd, bpfNetMaps, new Dependencies());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd,
|
||||
@NonNull final BpfNetMaps bpfNetMaps,
|
||||
@NonNull final Dependencies deps) {
|
||||
mPackageManager = context.getPackageManager();
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
@@ -197,6 +201,7 @@ public class PermissionMonitor {
|
||||
mNetd = netd;
|
||||
mDeps = deps;
|
||||
mContext = context;
|
||||
mBpfNetMaps = bpfNetMaps;
|
||||
}
|
||||
|
||||
private int getPackageNetdNetworkPermission(@NonNull final PackageInfo app) {
|
||||
@@ -803,9 +808,9 @@ public class PermissionMonitor {
|
||||
}
|
||||
try {
|
||||
if (add) {
|
||||
mNetd.firewallAddUidInterfaceRules(iface, toIntArray(uids));
|
||||
mBpfNetMaps.addUidInterfaceRules(iface, toIntArray(uids));
|
||||
} else {
|
||||
mNetd.firewallRemoveUidInterfaceRules(toIntArray(uids));
|
||||
mBpfNetMaps.removeUidInterfaceRules(toIntArray(uids));
|
||||
}
|
||||
} catch (ServiceSpecificException e) {
|
||||
// Silently ignore exception when device does not support eBPF, otherwise just log
|
||||
@@ -813,8 +818,6 @@ public class PermissionMonitor {
|
||||
if (e.errorCode != OsConstants.EOPNOTSUPP) {
|
||||
loge("Exception when updating permissions: ", e);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
loge("Exception when updating permissions: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -878,26 +881,27 @@ public class PermissionMonitor {
|
||||
try {
|
||||
// TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
|
||||
if (allPermissionAppIds.size() != 0) {
|
||||
mNetd.trafficSetNetPermForUids(
|
||||
mBpfNetMaps.setNetPermForUids(
|
||||
PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
|
||||
toIntArray(allPermissionAppIds));
|
||||
}
|
||||
if (internetPermissionAppIds.size() != 0) {
|
||||
mNetd.trafficSetNetPermForUids(PERMISSION_INTERNET,
|
||||
mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET,
|
||||
toIntArray(internetPermissionAppIds));
|
||||
}
|
||||
if (updateStatsPermissionAppIds.size() != 0) {
|
||||
mNetd.trafficSetNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
|
||||
mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
|
||||
toIntArray(updateStatsPermissionAppIds));
|
||||
}
|
||||
if (noPermissionAppIds.size() != 0) {
|
||||
mNetd.trafficSetNetPermForUids(PERMISSION_NONE, toIntArray(noPermissionAppIds));
|
||||
mBpfNetMaps.setNetPermForUids(PERMISSION_NONE,
|
||||
toIntArray(noPermissionAppIds));
|
||||
}
|
||||
if (uninstalledAppIds.size() != 0) {
|
||||
mNetd.trafficSetNetPermForUids(PERMISSION_UNINSTALLED,
|
||||
mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED,
|
||||
toIntArray(uninstalledAppIds));
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
} catch (ServiceSpecificException e) {
|
||||
Log.e(TAG, "Pass appId list of special permission failed." + e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user