mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[950-harden-deferred-unpack] Hardened deffered unpacking so it no longer throws
This commit is contained in:
@@ -101,6 +101,7 @@ extern const isc::log::MessageID DHCP4_PACKET_NAK_0002 = "DHCP4_PACKET_NAK_0002"
|
|||||||
extern const isc::log::MessageID DHCP4_PACKET_NAK_0003 = "DHCP4_PACKET_NAK_0003";
|
extern const isc::log::MessageID DHCP4_PACKET_NAK_0003 = "DHCP4_PACKET_NAK_0003";
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_NAK_0004 = "DHCP4_PACKET_NAK_0004";
|
extern const isc::log::MessageID DHCP4_PACKET_NAK_0004 = "DHCP4_PACKET_NAK_0004";
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_OPTIONS_SKIPPED = "DHCP4_PACKET_OPTIONS_SKIPPED";
|
extern const isc::log::MessageID DHCP4_PACKET_OPTIONS_SKIPPED = "DHCP4_PACKET_OPTIONS_SKIPPED";
|
||||||
|
extern const isc::log::MessageID DHCP4_PACKET_OPTION_UNPACK_FAIL = "DHCP4_PACKET_OPTION_UNPACK_FAIL";
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_PACK = "DHCP4_PACKET_PACK";
|
extern const isc::log::MessageID DHCP4_PACKET_PACK = "DHCP4_PACKET_PACK";
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_PACK_FAIL = "DHCP4_PACKET_PACK_FAIL";
|
extern const isc::log::MessageID DHCP4_PACKET_PACK_FAIL = "DHCP4_PACKET_PACK_FAIL";
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_PROCESS_EXCEPTION = "DHCP4_PACKET_PROCESS_EXCEPTION";
|
extern const isc::log::MessageID DHCP4_PACKET_PROCESS_EXCEPTION = "DHCP4_PACKET_PROCESS_EXCEPTION";
|
||||||
@@ -238,7 +239,8 @@ const char* values[] = {
|
|||||||
"DHCP4_PACKET_NAK_0002", "%1: invalid address %2 requested by INIT-REBOOT",
|
"DHCP4_PACKET_NAK_0002", "%1: invalid address %2 requested by INIT-REBOOT",
|
||||||
"DHCP4_PACKET_NAK_0003", "%1: failed to advertise a lease, client sent ciaddr %2, requested-ip-address %3",
|
"DHCP4_PACKET_NAK_0003", "%1: failed to advertise a lease, client sent ciaddr %2, requested-ip-address %3",
|
||||||
"DHCP4_PACKET_NAK_0004", "%1: failed to grant a lease, client sent ciaddr %2, requested-ip-address %3",
|
"DHCP4_PACKET_NAK_0004", "%1: failed to grant a lease, client sent ciaddr %2, requested-ip-address %3",
|
||||||
"DHCP4_PACKET_OPTIONS_SKIPPED", "An error upacking an option, caused subsequent options to be skipped: %1",
|
"DHCP4_PACKET_OPTIONS_SKIPPED", "An error unpacking an option, caused subsequent options to be skipped: %1",
|
||||||
|
"DHCP4_PACKET_OPTION_UNPACK_FAIL", "An error unpacking the option %1: %2",
|
||||||
"DHCP4_PACKET_PACK", "%1: preparing on-wire format of the packet to be sent",
|
"DHCP4_PACKET_PACK", "%1: preparing on-wire format of the packet to be sent",
|
||||||
"DHCP4_PACKET_PACK_FAIL", "%1: preparing on-wire-format of the packet to be sent failed %2",
|
"DHCP4_PACKET_PACK_FAIL", "%1: preparing on-wire-format of the packet to be sent failed %2",
|
||||||
"DHCP4_PACKET_PROCESS_EXCEPTION", "exception occurred during packet processing",
|
"DHCP4_PACKET_PROCESS_EXCEPTION", "exception occurred during packet processing",
|
||||||
|
@@ -102,6 +102,7 @@ extern const isc::log::MessageID DHCP4_PACKET_NAK_0002;
|
|||||||
extern const isc::log::MessageID DHCP4_PACKET_NAK_0003;
|
extern const isc::log::MessageID DHCP4_PACKET_NAK_0003;
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_NAK_0004;
|
extern const isc::log::MessageID DHCP4_PACKET_NAK_0004;
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_OPTIONS_SKIPPED;
|
extern const isc::log::MessageID DHCP4_PACKET_OPTIONS_SKIPPED;
|
||||||
|
extern const isc::log::MessageID DHCP4_PACKET_OPTION_UNPACK_FAIL;
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_PACK;
|
extern const isc::log::MessageID DHCP4_PACKET_PACK;
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_PACK_FAIL;
|
extern const isc::log::MessageID DHCP4_PACKET_PACK_FAIL;
|
||||||
extern const isc::log::MessageID DHCP4_PACKET_PROCESS_EXCEPTION;
|
extern const isc::log::MessageID DHCP4_PACKET_PROCESS_EXCEPTION;
|
||||||
|
@@ -558,7 +558,12 @@ identification information. The second argument contains the IPv4 address
|
|||||||
in the ciaddr field. The third argument contains the IPv4 address in the
|
in the ciaddr field. The third argument contains the IPv4 address in the
|
||||||
requested-ip-address option (if present).
|
requested-ip-address option (if present).
|
||||||
|
|
||||||
% DHCP4_PACKET_OPTIONS_SKIPPED An error upacking an option, caused subsequent options to be skipped: %1
|
% DHCP4_PACKET_OPTION_UNPACK_FAIL An error unpacking the option %1: %2
|
||||||
|
A debug message issued when an option failed to unpack correctly, making it
|
||||||
|
to be left unpacked in the packet. The first argument is the option code,
|
||||||
|
the second the error.
|
||||||
|
|
||||||
|
% DHCP4_PACKET_OPTIONS_SKIPPED An error unpacking an option, caused subsequent options to be skipped: %1
|
||||||
A debug message issued when an option failed to unpack correctly, making it
|
A debug message issued when an option failed to unpack correctly, making it
|
||||||
impossible to unpack the remaining options in the packet. The server will
|
impossible to unpack the remaining options in the packet. The server will
|
||||||
server will still attempt to service the packet.
|
server will still attempt to service the packet.
|
||||||
|
@@ -3598,14 +3598,28 @@ Dhcpv4Srv::deferredUnpack(Pkt4Ptr& query)
|
|||||||
OptionPtr opt = query->getOption(code);
|
OptionPtr opt = query->getOption(code);
|
||||||
if (!opt) {
|
if (!opt) {
|
||||||
// should not happen but do not crash anyway
|
// should not happen but do not crash anyway
|
||||||
|
LOG_DEBUG(bad_packet4_logger, DBG_DHCP4_DETAIL,
|
||||||
|
DHCP4_PACKET_OPTION_UNPACK_FAIL)
|
||||||
|
.arg(code)
|
||||||
|
.arg("can't find the option in the query");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const OptionBuffer buf = opt->getData();
|
const OptionBuffer buf = opt->getData();
|
||||||
|
try {
|
||||||
|
// Unpack the option
|
||||||
|
opt = def->optionFactory(Option::V4, code, buf);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
// Failed to parse the option.
|
||||||
|
LOG_DEBUG(bad_packet4_logger, DBG_DHCP4_DETAIL,
|
||||||
|
DHCP4_PACKET_OPTION_UNPACK_FAIL)
|
||||||
|
.arg(code)
|
||||||
|
.arg(e.what());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
while (query->delOption(code)) {
|
while (query->delOption(code)) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
// Unpack the option and add it
|
// Add the unpacked option.
|
||||||
opt = def->optionFactory(Option::V4, code, buf.cbegin(), buf.cend());
|
|
||||||
query->addOption(opt);
|
query->addOption(opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -684,7 +684,7 @@ TEST_F(VendorOptsTest, option43FailRaw) {
|
|||||||
// The vendor-encapsulated-options has an incompatible data
|
// The vendor-encapsulated-options has an incompatible data
|
||||||
// so won't have the expected content. Here the processing
|
// so won't have the expected content. Here the processing
|
||||||
// of suboptions tries to unpack the uitn32 foo suboption and
|
// of suboptions tries to unpack the uitn32 foo suboption and
|
||||||
// raises an exception.
|
// raises an exception which is caught so the option stays unpacked.
|
||||||
string config = "{ \"interfaces-config\": {"
|
string config = "{ \"interfaces-config\": {"
|
||||||
" \"interfaces\": [ \"*\" ] }, "
|
" \"interfaces\": [ \"*\" ] }, "
|
||||||
"\"subnet4\": [ "
|
"\"subnet4\": [ "
|
||||||
@@ -742,7 +742,9 @@ TEST_F(VendorOptsTest, option43FailRaw) {
|
|||||||
query->addOption(prl);
|
query->addOption(prl);
|
||||||
|
|
||||||
srv.classifyPacket(query);
|
srv.classifyPacket(query);
|
||||||
EXPECT_THROW(srv.deferredUnpack(query), InvalidOptionValue);
|
EXPECT_NO_THROW(srv.deferredUnpack(query));
|
||||||
|
ASSERT_TRUE(query->getOption(vopt->getType()));
|
||||||
|
EXPECT_EQ(vopt, query->getOption(vopt->getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifies raw option 43 can be handled (global)
|
// Verifies raw option 43 can be handled (global)
|
||||||
@@ -1321,7 +1323,7 @@ TEST_F(VendorOptsTest, clientOption43FailRaw) {
|
|||||||
// The vendor-encapsulated-options has an incompatible data
|
// The vendor-encapsulated-options has an incompatible data
|
||||||
// so won't have the expected content. Here the processing
|
// so won't have the expected content. Here the processing
|
||||||
// of suboptions tries to unpack the uint32 foo suboption and
|
// of suboptions tries to unpack the uint32 foo suboption and
|
||||||
// raises an exception.
|
// raises an exception which is caught.
|
||||||
string config = "{ \"interfaces-config\": {"
|
string config = "{ \"interfaces-config\": {"
|
||||||
" \"interfaces\": [ \"*\" ] }, "
|
" \"interfaces\": [ \"*\" ] }, "
|
||||||
"\"subnet4\": [ "
|
"\"subnet4\": [ "
|
||||||
@@ -1346,9 +1348,9 @@ TEST_F(VendorOptsTest, clientOption43FailRaw) {
|
|||||||
client.addExtraOption(vopt);
|
client.addExtraOption(vopt);
|
||||||
|
|
||||||
// Let's check whether the server is not able to process this packet
|
// Let's check whether the server is not able to process this packet
|
||||||
// and raises an exception so the response is empty.
|
// and raises an exception which is caught so the response is not empty.
|
||||||
EXPECT_NO_THROW(client.doDiscover());
|
EXPECT_NO_THROW(client.doDiscover());
|
||||||
EXPECT_FALSE(client.getContext().response_);
|
EXPECT_TRUE(client.getContext().response_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifies raw option 43 sent by a client can be handled (global)
|
// Verifies raw option 43 sent by a client can be handled (global)
|
||||||
|
Reference in New Issue
Block a user