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
diff --git a/service/src/com/android/server/connectivity/DscpPolicyTracker.java b/service/src/com/android/server/connectivity/DscpPolicyTracker.java
index 9c2b9e8..857d705 100644
--- a/service/src/com/android/server/connectivity/DscpPolicyTracker.java
+++ b/service/src/com/android/server/connectivity/DscpPolicyTracker.java
@@ -233,6 +233,11 @@
*/
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 a6b222f..eb119c8 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 @@
* @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 2a587b6..22b084c 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 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 ceccf0b..df4dab5 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 @@
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<OnDscpPolicyStatusUpdated>()
+ }
}
private fun ByteBuffer.readAsArray(): ByteArray {