Skip to content

Commit 0b98eae

Browse files
committed
[#3712] 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
1 parent 0b4ca4d commit 0b98eae

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

src/lib/dhcp/pkt_filter_lpf.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,14 @@ PktFilterLPF::receive(Iface& iface, const SocketInfo& socket_info) {
318318
decodeEthernetHeader(buf, dummy_pkt);
319319
decodeIpUdpHeader(buf, dummy_pkt);
320320

321+
auto v4_len = buf.getLength() - buf.getPosition();
322+
if (v4_len <= 0) {
323+
isc_throw(SocketReadError, "Pkt4FilterLpf:: packet has no DHCPv4 data");
324+
}
325+
321326
// Read the DHCP data.
322327
std::vector<uint8_t> dhcp_buf;
323-
buf.readVector(dhcp_buf, buf.getLength() - buf.getPosition());
328+
buf.readVector(dhcp_buf, v4_len);
324329

325330
// Decode DHCP data into the Pkt4 object.
326331
Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(&dhcp_buf[0], dhcp_buf.size()));
@@ -344,8 +349,7 @@ PktFilterLPF::receive(Iface& iface, const SocketInfo& socket_info) {
344349

345350
struct timeval cmsg_time;
346351
memcpy(&cmsg_time, CMSG_DATA(cmsg), sizeof(cmsg_time));
347-
pkt->addPktEvent(PktEvent::SOCKET_RECEIVED, cmsg_time);
348-
break;
352+
pkt->addPktEvent(PktEvent::SOCKET_RECEIVED, cmsg_time); break;
349353
}
350354

351355
cmsg = CMSG_NXTHDR(&m, cmsg);

src/lib/util/buffer.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2009-2024 Internet Systems Consortium, Inc. ("ISC")
1+
// Copyright (C) 2009-2025 Internet Systems Consortium, Inc. ("ISC")
22
//
33
// This Source Code Form is subject to the terms of the Mozilla Public
44
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -233,7 +233,8 @@ class InputBuffer {
233233
/// @details If specified buffer is too short, it will be expanded using
234234
/// vector::resize() method. If the remaining length of the buffer
235235
/// is smaller than the specified length, an exception of class
236-
/// @c isc::OutOfRange will be thrown.
236+
/// @c isc::OutOfRange will be thrown. Read length zero results
237+
/// in an empty vector.
237238
///
238239
/// @param data Reference to a buffer (data will be stored there).
239240
/// @param len Size specified number of bytes to read in a vector.
@@ -244,7 +245,9 @@ class InputBuffer {
244245
}
245246

246247
data.resize(len);
247-
peekData(&data[0], len);
248+
if (len) {
249+
peekData(&data[0], len);
250+
}
248251
}
249252

250253
/// @brief Read specified number of bytes as a vector.

src/lib/util/tests/buffer_unittest.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2009-2024 Internet Systems Consortium, Inc. ("ISC")
1+
// Copyright (C) 2009-2025 Internet Systems Consortium, Inc. ("ISC")
22
//
33
// This Source Code Form is subject to the terms of the Mozilla Public
44
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -197,6 +197,12 @@ TEST_F(BufferTest, inputBufferRead) {
197197
ASSERT_EQ(sizeof(vdata), datav.size());
198198
ASSERT_EQ(0, memcmp(&vdata[0], testdata, sizeof(testdata)));
199199
ASSERT_EQ(sizeof(vdata), ibuffer.getPosition());
200+
201+
// Verify that read len of zero results in an empty
202+
// vector without throwing.
203+
datav.resize(8);
204+
ASSERT_NO_THROW(ibuffer.readVector(datav, 0));
205+
ASSERT_EQ(datav.size(), 0);
200206
}
201207

202208
TEST_F(BufferTest, outputBufferReadAt) {

0 commit comments

Comments
 (0)