From fd3ab6b212d1db60d52ea105ac5d06df032fea12 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Sun, 9 Mar 2025 14:27:33 +0900 Subject: [PATCH] Don't crash the system server when a misconfigured agent adds a DSCP policy Additionally, when calling isEthernet(null), throw NPE instead of SIGSEGV. Test: New test in this patch Change-Id: Ie80b860d4befe65a1777d0ebeb18d1807c6375d0 --- .../connectivity/DscpPolicyTracker.java | 5 +++++ .../com/android/net/module/util/TcUtils.java | 4 +++- .../com_android_net_module_util_TcUtils.cpp | 4 ++++ .../net/src/android/net/cts/DscpPolicyTest.kt | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/service/src/com/android/server/connectivity/DscpPolicyTracker.java b/service/src/com/android/server/connectivity/DscpPolicyTracker.java index 9c2b9e8e56..857d7058db 100644 --- a/service/src/com/android/server/connectivity/DscpPolicyTracker.java +++ b/service/src/com/android/server/connectivity/DscpPolicyTracker.java @@ -233,6 +233,11 @@ public class DscpPolicyTracker { */ public void addDscpPolicy(NetworkAgentInfo nai, DscpPolicy policy) { String iface = nai.linkProperties.getInterfaceName(); + if (null == iface) { + Log.e(TAG, "DSCP policies are not supported on null interfaces."); + sendStatus(nai, policy.getPolicyId(), DSCP_POLICY_STATUS_REQUEST_DECLINED); + return; + } if (!isEthernet(iface)) { Log.e(TAG, "DSCP policies are not supported on raw IP interfaces."); sendStatus(nai, policy.getPolicyId(), DSCP_POLICY_STATUS_REQUEST_DECLINED); diff --git a/staticlibs/device/com/android/net/module/util/TcUtils.java b/staticlibs/device/com/android/net/module/util/TcUtils.java index a6b222f1b2..eb119c871e 100644 --- a/staticlibs/device/com/android/net/module/util/TcUtils.java +++ b/staticlibs/device/com/android/net/module/util/TcUtils.java @@ -16,6 +16,8 @@ package com.android.net.module.util; +import androidx.annotation.NonNull; + import java.io.IOException; /** @@ -33,7 +35,7 @@ public class TcUtils { * @return true if the interface uses an ethernet L2 header. * @throws IOException */ - public static native boolean isEthernet(String iface) throws IOException; + public static native boolean isEthernet(@NonNull String iface) throws IOException; /** * Attach a tc bpf filter. diff --git a/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp index 2a587b6423..22b084cf7f 100644 --- a/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp +++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp @@ -32,6 +32,10 @@ static void throwIOException(JNIEnv *env, const char *msg, int error) { static jboolean com_android_net_module_util_TcUtils_isEthernet(JNIEnv *env, jclass clazz, jstring iface) { + if (nullptr == iface) { + jniThrowNullPointerException(env, "iface is null"); + return false; + } ScopedUtfChars interface(env, iface); bool result = false; int error = isEthernet(interface.c_str(), result); diff --git a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt index ceccf0bbfe..df4dab5544 100644 --- a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt +++ b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt @@ -757,6 +757,25 @@ class DscpPolicyTest { assertEquals(IPPROTO_UDP, policy2.protocol) assertParcelingIsLossless(policy2) } + + @Test + fun testSendDscpPolicyWithoutInterfaceName() { + val nc = NetworkCapabilities().apply { + addTransportType(TRANSPORT_TEST) + } + val agent = TestableNetworkAgent( + realContext, + handlerThread.looper, + nc, + LinkProperties() /* note: no interface name */, + NetworkAgentConfig.Builder().build() + ) + agentsToCleanUp.add(agent) + runAsShell(MANAGE_TEST_NETWORKS) { agent.register() } + // Without the fix, this will crash the system with SIGSEGV. + agent.sendAddDscpPolicy(DscpPolicy.Builder(1, 1).build()) + agent.expectCallback() + } } private fun ByteBuffer.readAsArray(): ByteArray {