Loading core/java/android/net/NetworkUtils.java +8 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,14 @@ public class NetworkUtils { */ public static native Network getDnsNetwork() throws ErrnoException; /** * Allow/Disallow creating AF_INET/AF_INET6 sockets and DNS lookups for current process. * * @param allowNetworking whether to allow or disallow creating AF_INET/AF_INET6 sockets * and DNS lookups. */ public static native void setAllowNetworkingForProcess(boolean allowNetworking); /** * Get the tcp repair window associated with the {@code fd}. * Loading core/java/android/os/Process.java +7 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,13 @@ public class Process { */ public static final int EXT_OBB_RW_GID = 1079; /** * GID that corresponds to the INTERNET permission. * Must match the value of AID_INET. * @hide */ public static final int INET_GID = 3003; /** {@hide} */ public static final int NOBODY_UID = 9999; Loading core/java/com/android/internal/os/Zygote.java +13 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.pm.ApplicationInfo; import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.NetworkUtils; import android.os.FactoryTest; import android.os.IVold; import android.os.Process; Loading Loading @@ -286,6 +287,13 @@ public final class Zygote { private Zygote() {} private static boolean containsInetGid(int[] gids) { for (int i = 0; i < gids.length; i++) { if (gids[i] == android.os.Process.INET_GID) return true; } return false; } /** * Forks a new VM instance. The current VM must have been started * with the -Xzygote flag. <b>NOTE: new instance keeps all Loading Loading @@ -341,6 +349,11 @@ public final class Zygote { if (pid == 0) { // Note that this event ends at the end of handleChildProc, Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); // If no GIDs were specified, don't make any permissions changes based on groups. if (gids != null && gids.length > 0) { NetworkUtils.setAllowNetworkingForProcess(containsInetGid(gids)); } } // Set the Java Language thread priority to the default value for new apps. Loading core/jni/android_net_NetUtils.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -226,6 +226,11 @@ static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) { class_Network, ctor, dnsNetId & ~NETID_USE_LOCAL_NAMESERVERS, privateDnsBypass); } static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz, jboolean hasConnectivity) { setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE); } static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) { if (javaFd == NULL) { jniThrowNullPointerException(env, NULL); Loading Loading @@ -266,6 +271,7 @@ static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, j /* * JNI registration. */ // clang-format off static const JNINativeMethod gNetworkUtilMethods[] = { /* name, signature, funcPtr */ { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork }, Loading @@ -282,7 +288,9 @@ static const JNINativeMethod gNetworkUtilMethods[] = { { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult }, { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel }, { "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork }, { "setAllowNetworkingForProcess", "(Z)V", (void *)android_net_utils_setAllowNetworkingForProcess }, }; // clang-format on int register_android_net_NetworkUtils(JNIEnv* env) { Loading tests/net/java/android/net/NetworkUtilsTest.java +60 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,24 @@ package android.net; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; import static android.system.OsConstants.AF_UNIX; import static android.system.OsConstants.EPERM; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_STREAM; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.fail; import android.system.ErrnoException; import android.system.Os; import androidx.test.runner.AndroidJUnit4; import libcore.io.IoUtils; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -125,4 +139,50 @@ public class NetworkUtilsTest { assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536), NetworkUtils.routedIPv6AddressCount(set)); } private static void expectSocketSuccess(String msg, int domain, int type) { try { IoUtils.closeQuietly(Os.socket(domain, type, 0)); } catch (ErrnoException e) { fail(msg + e.getMessage()); } } private static void expectSocketPemissionError(String msg, int domain, int type) { try { IoUtils.closeQuietly(Os.socket(domain, type, 0)); fail(msg); } catch (ErrnoException e) { assertEquals(msg, e.errno, EPERM); } } private static void expectHasNetworking() { expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", AF_UNIX, SOCK_STREAM); expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException", AF_INET, SOCK_DGRAM); expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException", AF_INET6, SOCK_DGRAM); } private static void expectNoNetworking() { expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", AF_UNIX, SOCK_STREAM); expectSocketPemissionError( "Creating a AF_INET socket should have thrown ErrnoException(EPERM)", AF_INET, SOCK_DGRAM); expectSocketPemissionError( "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)", AF_INET6, SOCK_DGRAM); } @Test public void testSetAllowNetworkingForProcess() { expectHasNetworking(); NetworkUtils.setAllowNetworkingForProcess(false); expectNoNetworking(); NetworkUtils.setAllowNetworkingForProcess(true); expectHasNetworking(); } } Loading
core/java/android/net/NetworkUtils.java +8 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,14 @@ public class NetworkUtils { */ public static native Network getDnsNetwork() throws ErrnoException; /** * Allow/Disallow creating AF_INET/AF_INET6 sockets and DNS lookups for current process. * * @param allowNetworking whether to allow or disallow creating AF_INET/AF_INET6 sockets * and DNS lookups. */ public static native void setAllowNetworkingForProcess(boolean allowNetworking); /** * Get the tcp repair window associated with the {@code fd}. * Loading
core/java/android/os/Process.java +7 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,13 @@ public class Process { */ public static final int EXT_OBB_RW_GID = 1079; /** * GID that corresponds to the INTERNET permission. * Must match the value of AID_INET. * @hide */ public static final int INET_GID = 3003; /** {@hide} */ public static final int NOBODY_UID = 9999; Loading
core/java/com/android/internal/os/Zygote.java +13 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.pm.ApplicationInfo; import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.NetworkUtils; import android.os.FactoryTest; import android.os.IVold; import android.os.Process; Loading Loading @@ -286,6 +287,13 @@ public final class Zygote { private Zygote() {} private static boolean containsInetGid(int[] gids) { for (int i = 0; i < gids.length; i++) { if (gids[i] == android.os.Process.INET_GID) return true; } return false; } /** * Forks a new VM instance. The current VM must have been started * with the -Xzygote flag. <b>NOTE: new instance keeps all Loading Loading @@ -341,6 +349,11 @@ public final class Zygote { if (pid == 0) { // Note that this event ends at the end of handleChildProc, Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); // If no GIDs were specified, don't make any permissions changes based on groups. if (gids != null && gids.length > 0) { NetworkUtils.setAllowNetworkingForProcess(containsInetGid(gids)); } } // Set the Java Language thread priority to the default value for new apps. Loading
core/jni/android_net_NetUtils.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -226,6 +226,11 @@ static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) { class_Network, ctor, dnsNetId & ~NETID_USE_LOCAL_NAMESERVERS, privateDnsBypass); } static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz, jboolean hasConnectivity) { setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE); } static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) { if (javaFd == NULL) { jniThrowNullPointerException(env, NULL); Loading Loading @@ -266,6 +271,7 @@ static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, j /* * JNI registration. */ // clang-format off static const JNINativeMethod gNetworkUtilMethods[] = { /* name, signature, funcPtr */ { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork }, Loading @@ -282,7 +288,9 @@ static const JNINativeMethod gNetworkUtilMethods[] = { { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult }, { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel }, { "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork }, { "setAllowNetworkingForProcess", "(Z)V", (void *)android_net_utils_setAllowNetworkingForProcess }, }; // clang-format on int register_android_net_NetworkUtils(JNIEnv* env) { Loading
tests/net/java/android/net/NetworkUtilsTest.java +60 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,24 @@ package android.net; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; import static android.system.OsConstants.AF_UNIX; import static android.system.OsConstants.EPERM; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_STREAM; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.fail; import android.system.ErrnoException; import android.system.Os; import androidx.test.runner.AndroidJUnit4; import libcore.io.IoUtils; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -125,4 +139,50 @@ public class NetworkUtilsTest { assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536), NetworkUtils.routedIPv6AddressCount(set)); } private static void expectSocketSuccess(String msg, int domain, int type) { try { IoUtils.closeQuietly(Os.socket(domain, type, 0)); } catch (ErrnoException e) { fail(msg + e.getMessage()); } } private static void expectSocketPemissionError(String msg, int domain, int type) { try { IoUtils.closeQuietly(Os.socket(domain, type, 0)); fail(msg); } catch (ErrnoException e) { assertEquals(msg, e.errno, EPERM); } } private static void expectHasNetworking() { expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", AF_UNIX, SOCK_STREAM); expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException", AF_INET, SOCK_DGRAM); expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException", AF_INET6, SOCK_DGRAM); } private static void expectNoNetworking() { expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", AF_UNIX, SOCK_STREAM); expectSocketPemissionError( "Creating a AF_INET socket should have thrown ErrnoException(EPERM)", AF_INET, SOCK_DGRAM); expectSocketPemissionError( "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)", AF_INET6, SOCK_DGRAM); } @Test public void testSetAllowNetworkingForProcess() { expectHasNetworking(); NetworkUtils.setAllowNetworkingForProcess(false); expectNoNetworking(); NetworkUtils.setAllowNetworkingForProcess(true); expectHasNetworking(); } }