Merge "Re-implement NetworkUtils#queryUserAccess."

This commit is contained in:
Remi NGUYEN VAN
2021-03-29 04:57:40 +00:00
committed by Gerrit Code Review
5 changed files with 51 additions and 11 deletions

View File

@@ -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 },

View File

@@ -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.

View File

@@ -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);

View File

@@ -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<>();

View File

@@ -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));