Merge "Re-implement NetworkUtils#queryUserAccess."
This commit is contained in:
@@ -102,11 +102,6 @@ static jint android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, job
|
||||
return setNetworkForSocket(netId, AFileDescriptor_getFD(env, javaFd));
|
||||
}
|
||||
|
||||
static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jint uid, jint netId)
|
||||
{
|
||||
return (jboolean) !queryUserAccess(uid, netId);
|
||||
}
|
||||
|
||||
static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst)
|
||||
{
|
||||
if (env->GetArrayLength(addr) != len) {
|
||||
@@ -246,7 +241,6 @@ static const JNINativeMethod gNetworkUtilMethods[] = {
|
||||
{ "getBoundNetworkForProcess", "()I", (void*) android_net_utils_getBoundNetworkForProcess },
|
||||
{ "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
|
||||
{ "bindSocketToNetwork", "(Ljava/io/FileDescriptor;I)I", (void*) android_net_utils_bindSocketToNetwork },
|
||||
{ "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
|
||||
{ "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
|
||||
{ "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
|
||||
{ "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow },
|
||||
|
||||
@@ -92,7 +92,10 @@ public class NetworkUtils {
|
||||
* Determine if {@code uid} can access network designated by {@code netId}.
|
||||
* @return {@code true} if {@code uid} can access network, {@code false} otherwise.
|
||||
*/
|
||||
public native static boolean queryUserAccess(int uid, int netId);
|
||||
public static boolean queryUserAccess(int uid, int netId) {
|
||||
// TODO (b/183485986): remove this method
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* DNS resolver series jni method.
|
||||
|
||||
@@ -1149,8 +1149,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
/**
|
||||
* @see NetworkUtils#queryUserAccess(int, int)
|
||||
*/
|
||||
public boolean queryUserAccess(int uid, int netId) {
|
||||
return NetworkUtils.queryUserAccess(uid, netId);
|
||||
public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) {
|
||||
return cs.queryUserAccess(uid, network);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4843,6 +4843,42 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
nai.networkMonitor().forceReevaluation(uid);
|
||||
}
|
||||
|
||||
// TODO: call into netd.
|
||||
private boolean queryUserAccess(int uid, Network network) {
|
||||
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
||||
if (nai == null) return false;
|
||||
|
||||
// Any UID can use its default network.
|
||||
if (nai == getDefaultNetworkForUid(uid)) return true;
|
||||
|
||||
// Privileged apps can use any network.
|
||||
if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// An unprivileged UID can use a VPN iff the VPN applies to it.
|
||||
if (nai.isVPN()) {
|
||||
return nai.networkCapabilities.appliesToUid(uid);
|
||||
}
|
||||
|
||||
// An unprivileged UID can bypass the VPN that applies to it only if it can protect its
|
||||
// sockets, i.e., if it is the owner.
|
||||
final NetworkAgentInfo vpn = getVpnForUid(uid);
|
||||
if (vpn != null && !vpn.networkAgentConfig.allowBypass
|
||||
&& uid != vpn.networkCapabilities.getOwnerUid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The UID's permission must be at least sufficient for the network. Since the restricted
|
||||
// permission was already checked above, that just leaves background networks.
|
||||
if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) {
|
||||
return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid);
|
||||
}
|
||||
|
||||
// Unrestricted network. Anyone gets to use it.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the proxy a certain network is using. If given a null network, it
|
||||
* it will return the proxy for the bound network for the caller app or the default proxy if
|
||||
@@ -4863,7 +4899,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return null;
|
||||
}
|
||||
return getLinkPropertiesProxyInfo(activeNetwork);
|
||||
} else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network.getNetId())) {
|
||||
} else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) {
|
||||
// Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
|
||||
// caller may not have.
|
||||
return getLinkPropertiesProxyInfo(network);
|
||||
|
||||
@@ -271,6 +271,13 @@ public class PermissionMonitor {
|
||||
return mApps.containsKey(uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given uid has permission to use restricted networks.
|
||||
*/
|
||||
public synchronized boolean hasRestrictedNetworksPermission(int uid) {
|
||||
return Boolean.TRUE.equals(mApps.get(uid));
|
||||
}
|
||||
|
||||
private void update(Set<UserHandle> users, Map<Integer, Boolean> apps, boolean add) {
|
||||
List<Integer> network = new ArrayList<>();
|
||||
List<Integer> system = new ArrayList<>();
|
||||
|
||||
@@ -1571,7 +1571,7 @@ public class ConnectivityServiceTest {
|
||||
doReturn(mNetworkStack).when(deps).getNetworkStack();
|
||||
doReturn(mSystemProperties).when(deps).getSystemProperties();
|
||||
doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
|
||||
doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
|
||||
doReturn(true).when(deps).queryUserAccess(anyInt(), any(), any());
|
||||
doAnswer(inv -> {
|
||||
mPolicyTracker = new WrappedMultinetworkPolicyTracker(
|
||||
inv.getArgument(0), inv.getArgument(1), inv.getArgument(2));
|
||||
|
||||
Reference in New Issue
Block a user