]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3750] Backport #3712 to 2.6.2
authorThomas Markwalder <tmark@isc.org>
Fri, 28 Feb 2025 16:19:36 +0000 (11:19 -0500)
committerThomas Markwalder <tmark@isc.org>
Tue, 4 Mar 2025 15:31:23 +0000 (15:31 +0000)
Avoid assert on empty packet

/src/lib/dhcp/pkt_filter_lpf.cc
    PktFilterLPF::receive() - throw if packet has no data

/src/lib/util/buffer.h
    InputBuffer::readVecotr() - avoid peek if read request length is 0

/src/lib/util/tests/buffer_unittest.cc
    Updated test

src/lib/dhcp/pkt_filter_lpf.cc
src/lib/util/buffer.h
src/lib/util/tests/buffer_unittest.cc

index 69bdecc0e17b4ac6e3b88ab790be1e5088a8b1c1..d800cdce345cb76c4a44a66705535dd89e5fbe2b 100644 (file)
@@ -318,9 +318,14 @@ PktFilterLPF::receive(Iface& iface, const SocketInfo& socket_info) {
     decodeEthernetHeader(buf, dummy_pkt);
     decodeIpUdpHeader(buf, dummy_pkt);
 
+    auto v4_len = buf.getLength() - buf.getPosition();
+    if (v4_len <= 0) {
+        isc_throw(SocketReadError, "Pkt4FilterLpf packet has no DHCPv4 data");
+    }
+
     // Read the DHCP data.
     std::vector<uint8_t> dhcp_buf;
-    buf.readVector(dhcp_buf, buf.getLength() - buf.getPosition());
+    buf.readVector(dhcp_buf, v4_len);
 
     // Decode DHCP data into the Pkt4 object.
     Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(&dhcp_buf[0], dhcp_buf.size()));
@@ -344,8 +349,7 @@ PktFilterLPF::receive(Iface& iface, const SocketInfo& socket_info) {
 
             struct timeval cmsg_time;
             memcpy(&cmsg_time, CMSG_DATA(cmsg), sizeof(cmsg_time));
-            pkt->addPktEvent(PktEvent::SOCKET_RECEIVED, cmsg_time);
-            break;
+            pkt->addPktEvent(PktEvent::SOCKET_RECEIVED, cmsg_time); break;
         }
 
         cmsg = CMSG_NXTHDR(&m, cmsg);
index 41ecdf3375bd178a1b38eb617af5c0477fd7d2c4..c426a14495dc0291bda8244daef8c2954bc05006 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009-2024 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2009-2025 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -233,7 +233,8 @@ public:
     /// @details If specified buffer is too short, it will be expanded using
     /// vector::resize() method. If the remaining length of the buffer
     /// is smaller than the specified length, an exception of class
-    /// @c isc::OutOfRange will be thrown.
+    /// @c isc::OutOfRange will be thrown.  Read length zero results
+    /// in an empty vector.
     ///
     /// @param data Reference to a buffer (data will be stored there).
     /// @param len Size specified number of bytes to read in a vector.
@@ -244,7 +245,9 @@ public:
         }
 
         data.resize(len);
-        peekData(&data[0], len);
+        if (len) {
+            peekData(&data[0], len);
+        }
     }
 
     /// @brief Read specified number of bytes as a vector.
index 66c43e8f21473e305207b52519beaa2953435289..bae051dd16edc12ac0de170efb8743306903c857 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009-2024 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2009-2025 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -197,6 +197,12 @@ TEST_F(BufferTest, inputBufferRead) {
     ASSERT_EQ(sizeof(vdata), datav.size());
     ASSERT_EQ(0, memcmp(&vdata[0], testdata, sizeof(testdata)));
     ASSERT_EQ(sizeof(vdata), ibuffer.getPosition());
+
+    // Verify that read len of zero results in an empty
+    // vector without throwing.
+    datav.resize(8);
+    ASSERT_NO_THROW(ibuffer.readVector(datav, 0));
+    ASSERT_EQ(datav.size(), 0);
 }
 
 TEST_F(BufferTest, outputBufferReadAt) {