Merge "bpf_map_def: undo incorrect comment change." into main
diff --git a/bpf/progs/clatd.c b/bpf/progs/clatd.c
index 2d4551e..2bb9d6f 100644
--- a/bpf/progs/clatd.c
+++ b/bpf/progs/clatd.c
@@ -288,6 +288,9 @@
     // We cannot handle IP options, just standard 20 byte == 5 dword minimal IPv4 header
     if (ip4->ihl != 5) return TC_ACT_PIPE;
 
+    // Packet must not be multicast
+    if ((ip4->daddr & 0xf0000000) == 0xe0000000) return TC_ACT_PIPE;
+
     // Calculate the IPv4 one's complement checksum of the IPv4 header.
     __wsum sum4 = 0;
     for (unsigned i = 0; i < sizeof(*ip4) / sizeof(__u16); ++i) {
diff --git a/clatd/ipv4.c b/clatd/ipv4.c
index 2be02e3..81bf87b 100644
--- a/clatd/ipv4.c
+++ b/clatd/ipv4.c
@@ -85,6 +85,11 @@
     return 0;
   }
 
+  if ((header->daddr & 0xf0000000) == 0xe0000000) {
+    logmsg_dbg(ANDROID_LOG_INFO, "ip_packet/daddr is multicast: %x", header->daddr);
+    return 0;
+  }
+
   /* rfc6145 - If any IPv4 options are present in the IPv4 packet, they MUST be
    * ignored and the packet translated normally; there is no attempt to
    * translate the options.
diff --git a/tests/unit/java/com/android/server/net/HeaderCompressionUtilsTest.kt b/tests/unit/java/com/android/server/net/HeaderCompressionUtilsTest.kt
index 8431194..7ebe384 100644
--- a/tests/unit/java/com/android/server/net/HeaderCompressionUtilsTest.kt
+++ b/tests/unit/java/com/android/server/net/HeaderCompressionUtilsTest.kt
@@ -17,12 +17,14 @@
 package com.android.server.net
 
 import android.os.Build
+import com.android.internal.util.HexDump
 import com.android.testutils.ConnectivityModuleTest
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRunner
-import com.android.internal.util.HexDump
 import com.google.common.truth.Truth.assertThat
-
+import java.io.IOException
+import java.nio.BufferUnderflowException
+import kotlin.test.assertFailsWith
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -184,6 +186,83 @@
     }
 
     @Test
+    fun testHeaderDecompression_invalidPacket() {
+        // 1-byte packet
+        var input = "60"
+        assertFailsWith(BufferUnderflowException::class) { decompressHex(input) }
+
+        // Short packet -- incomplete header
+        // TF: 11, NH: 0, HLIM: 11, CID: 0, SAC: 0, SAM: 10, M: 1, DAC: 0, DAM: 11
+        input  = "7b2b" +
+                 "44" +                               // next header
+                 "1234"                               // source
+        assertFailsWith(BufferUnderflowException::class) { decompressHex(input) }
+
+        // Packet starts with 0b111 instead of 0b011
+        // TF: 11, NH: 0, HLIM: 11, CID: 0, SAC: 0, SAM: 10, M: 1, DAC: 0, DAM: 11
+        input  = "fb2b" +
+                 "44" +                               // next header
+                 "1234" +                             // source
+                 "89" +                               // dest
+                 "abcdef01"                           // payload
+        assertFailsWith(IOException::class) { decompressHex(input) }
+
+        // Illegal option NH = 1. Note that the packet is not valid as the code should throw as soon
+        // as the illegal option is encountered.
+        // TF: 11, NH: 1, HLIM: 11, CID: 0, SAC: 0, SAM: 10, M: 1, DAC: 0, DAM: 11
+        input  = "7f2b" +
+                 "1234" +                             // source
+                 "89" +                               // dest
+                 "e0"                                 // Hop-by-hop options NHC
+        assertFailsWith(IOException::class) { decompressHex(input) }
+
+        // Illegal option CID = 1.
+        // TF: 11, NH: 0, HLIM: 11, CID: 1, SAC: 0, SAM: 10, M: 1, DAC: 0, DAM: 11
+        input  = "7bab00" +
+                 "1234" +                             // source
+                 "89" +                               // dest
+                 "e0"                                 // Hop-by-hop options NHC
+        assertFailsWith(IOException::class) { decompressHex(input) }
+
+        // Illegal option SAC = 1.
+        // TF: 11, NH: 0, HLIM: 11, CID: 0, SAC: 1, SAM: 10, M: 1, DAC: 0, DAM: 11
+        input  = "7b6b" +
+                 "1234" +                             // source
+                 "89" +                               // dest
+                 "e0"                                 // Hop-by-hop options NHC
+        assertFailsWith(IOException::class) { decompressHex(input) }
+
+        // Illegal option DAC = 1.
+        // TF: 10, NH: 0, HLIM: 10, CID: 0, SAC: 0, SAM: 10, M: 0, DAC: 1, DAM: 10
+        input  = "7226" +
+                 "cc" +                               // traffic class
+                 "43" +                               // next header
+                 "1234" +                             // source
+                 "abcd" +                             // dest
+                 "abcdef"                             // payload
+        assertFailsWith(IOException::class) { decompressHex(input) }
+
+
+        // Unsupported option DAM = 11
+        // TF: 10, NH: 0, HLIM: 10, CID: 0, SAC: 0, SAM: 10, M: 0, DAC: 0, DAM: 11
+        input  = "7223" +
+                 "cc" +                               // traffic class
+                 "43" +                               // next header
+                 "1234" +                             // source
+                 "abcdef"                             // payload
+        assertFailsWith(IOException::class) { decompressHex(input) }
+
+        // Unsupported option SAM = 11
+        // TF: 10, NH: 0, HLIM: 10, CID: 0, SAC: 0, SAM: 11, M: 0, DAC: 0, DAM: 10
+        input  = "7232" +
+                 "cc" +                               // traffic class
+                 "43" +                               // next header
+                 "abcd" +                             // dest
+                 "abcdef"                             // payload
+        assertFailsWith(IOException::class) { decompressHex(input) }
+    }
+
+    @Test
     fun testHeaderCompression() {
         val input  = "60120304000011fffe800000000000000000000000000001fe800000000000000000000000000002"
         val output = "60000102030411fffe800000000000000000000000000001fe800000000000000000000000000002"