From: Marcin Siodelski Date: Tue, 26 Jun 2018 12:49:36 +0000 (+0200) Subject: [5651] Guard against invalid address family. X-Git-Tag: trac5694_base~5^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=74e13e92fed6987808d398364ab622802e3a81d0;p=thirdparty%2Fkea.git [5651] Guard against invalid address family. --- diff --git a/src/lib/dhcpsrv/cql_lease_mgr.cc b/src/lib/dhcpsrv/cql_lease_mgr.cc index 50bf89cac9..e1c995dce1 100644 --- a/src/lib/dhcpsrv/cql_lease_mgr.cc +++ b/src/lib/dhcpsrv/cql_lease_mgr.cc @@ -1,3 +1,4 @@ +// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2015-2018 Deutsche Telekom AG. // // Authors: Razvan Becheriu @@ -2149,6 +2150,13 @@ CqlLeaseMgr::getLeases4() const { Lease4Collection CqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, const LeasePageSize& page_size) const { + // Expecting IPv4 address. + if (!lower_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected IPv4 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + if (page_size.page_size_ == 0) { isc_throw(OutOfRange, "page size of retrieved leases must not be 0"); } @@ -2187,6 +2195,13 @@ CqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, Lease4Collection CqlLeaseMgr::getLeases4(const IOAddress& lower_bound_address, const IOAddress& upper_bound_address) const { + // Expecting two IPv4 addresses. + if (!lower_bound_address.isV4() || !upper_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected two IPv4 addresses for " + "retrieving a range of leases, got " + << lower_bound_address << " and " << upper_bound_address); + } + if (upper_bound_address < lower_bound_address) { isc_throw(InvalidRange, "upper bound address " << upper_bound_address << " is lower than lower bound address " << lower_bound_address); @@ -2315,6 +2330,13 @@ CqlLeaseMgr::getLeases6() const { Lease6Collection CqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, const LeasePageSize& page_size) const { + // Expecting IPv6 address. + if (!lower_bound_address.isV6()) { + isc_throw(InvalidAddressFamily, "expected IPv6 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + if (page_size.page_size_ == 0) { isc_throw(OutOfRange, "page size of retrieved leases must not be 0"); } diff --git a/src/lib/dhcpsrv/db_exceptions.h b/src/lib/dhcpsrv/db_exceptions.h index 64e99f4612..1bf92a38bf 100644 --- a/src/lib/dhcpsrv/db_exceptions.h +++ b/src/lib/dhcpsrv/db_exceptions.h @@ -67,6 +67,13 @@ public: isc::Exception(file, line, what) {} }; +/// @brief Invalid address family used as input to Lease Manager. +class InvalidAddressFamily : public Exception { +public: + InvalidAddressFamily(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) {} +}; + } // namespace isc } // namespace dhcp diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.cc b/src/lib/dhcpsrv/memfile_lease_mgr.cc index 2806f60184..4541b59aae 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.cc +++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc @@ -887,6 +887,13 @@ Memfile_LeaseMgr::getLeases4() const { Lease4Collection Memfile_LeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, const LeasePageSize& page_size) const { + // Expecting IPv4 address. + if (!lower_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected IPv4 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_PAGE4) .arg(page_size.page_size_) .arg(lower_bound_address.toText()); @@ -913,6 +920,13 @@ Memfile_LeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, Lease4Collection Memfile_LeaseMgr::getLeases4(const IOAddress& lower_bound_address, const IOAddress& upper_bound_address) const { + // Expecting two IPv4 addresses. + if (!lower_bound_address.isV4() || !upper_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected two IPv4 addresses for " + "retrieving a range of leases, got " + << lower_bound_address << " and " << upper_bound_address); + } + // Check if the range boundaries aren't swapped. if (upper_bound_address < lower_bound_address) { isc_throw(InvalidRange, "upper bound address " << upper_bound_address @@ -1038,6 +1052,13 @@ Memfile_LeaseMgr::getLeases6() const { Lease6Collection Memfile_LeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, const LeasePageSize& page_size) const { + // Expecting IPv6 address. + if (!lower_bound_address.isV6()) { + isc_throw(InvalidAddressFamily, "expected IPv6 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_PAGE6) .arg(page_size.page_size_) .arg(lower_bound_address.toText()); @@ -1064,6 +1085,13 @@ Memfile_LeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, Lease6Collection Memfile_LeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, const asiolink::IOAddress& upper_bound_address) const { + // Expecting two IPv6 addresses. + if (!lower_bound_address.isV6() || !upper_bound_address.isV6()) { + isc_throw(InvalidAddressFamily, "expected two IPv6 addresses for " + "retrieving a range of leases, got " + << lower_bound_address << " and " << upper_bound_address); + } + // Check if the range boundaries aren't swapped. if (upper_bound_address < lower_bound_address) { isc_throw(InvalidRange, "upper bound address " << upper_bound_address diff --git a/src/lib/dhcpsrv/mysql_lease_mgr.cc b/src/lib/dhcpsrv/mysql_lease_mgr.cc index 74081eb96f..b437856a7b 100644 --- a/src/lib/dhcpsrv/mysql_lease_mgr.cc +++ b/src/lib/dhcpsrv/mysql_lease_mgr.cc @@ -1943,6 +1943,13 @@ MySqlLeaseMgr::getLeases4() const { Lease4Collection MySqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, const LeasePageSize& page_size) const { + // Expecting IPv4 address. + if (!lower_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected IPv4 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_PAGE4) .arg(page_size.page_size_) .arg(lower_bound_address.toText()); @@ -1973,6 +1980,13 @@ MySqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, Lease4Collection MySqlLeaseMgr::getLeases4(const IOAddress& lower_bound_address, const IOAddress& upper_bound_address) const { + // Expecting two IPv4 addresses. + if (!lower_bound_address.isV4() || !upper_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected two IPv4 addresses for " + "retrieving a range of leases, got " + << lower_bound_address << " and " << upper_bound_address); + } + if (upper_bound_address < lower_bound_address) { isc_throw(InvalidRange, "upper bound address " << upper_bound_address << " is lower than lower bound address " << lower_bound_address); @@ -2164,6 +2178,13 @@ MySqlLeaseMgr::getLeases6() const { Lease6Collection MySqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, const LeasePageSize& page_size) const { + // Expecting IPv6 address. + if (!lower_bound_address.isV6()) { + isc_throw(InvalidAddressFamily, "expected IPv6 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_PAGE6) .arg(page_size.page_size_) .arg(lower_bound_address.toText()); @@ -2203,6 +2224,13 @@ MySqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, Lease6Collection MySqlLeaseMgr::getLeases6(const IOAddress& lower_bound_address, const IOAddress& upper_bound_address) const { + // Expecting two IPv6 addresses. + if (!lower_bound_address.isV6() || !upper_bound_address.isV6()) { + isc_throw(InvalidAddressFamily, "expected two IPv6 addresses for " + "retrieving a range of leases, got " + << lower_bound_address << " and " << upper_bound_address); + } + if (upper_bound_address < lower_bound_address) { isc_throw(InvalidRange, "upper bound address " << upper_bound_address << " is lower than lower bound address " << lower_bound_address); diff --git a/src/lib/dhcpsrv/pgsql_lease_mgr.cc b/src/lib/dhcpsrv/pgsql_lease_mgr.cc index 5d3d4ba6a0..8676c0185f 100644 --- a/src/lib/dhcpsrv/pgsql_lease_mgr.cc +++ b/src/lib/dhcpsrv/pgsql_lease_mgr.cc @@ -1343,7 +1343,14 @@ PgSqlLeaseMgr::getLeases4() const { Lease4Collection PgSqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, - const LeasePageSize& page_size) const { + const LeasePageSize& page_size) const { + // Expecting IPv4 address. + if (!lower_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected IPv4 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_PAGE4) .arg(page_size.page_size_) .arg(lower_bound_address.toText()); @@ -1370,6 +1377,13 @@ PgSqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address, Lease4Collection PgSqlLeaseMgr::getLeases4(const IOAddress& lower_bound_address, const IOAddress& upper_bound_address) const { + // Expecting two IPv4 addresses. + if (!lower_bound_address.isV4() || !upper_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected two IPv4 addresses for " + "retrieving a range of leases, got " + << lower_bound_address << " and " << upper_bound_address); + } + if (upper_bound_address < lower_bound_address) { isc_throw(InvalidRange, "upper bound address " << upper_bound_address << " is lower than lower bound address " << lower_bound_address); @@ -1518,6 +1532,13 @@ PgSqlLeaseMgr::getLeases6() const { Lease6Collection PgSqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, const LeasePageSize& page_size) const { + // Expecting IPv6 address. + if (!lower_bound_address.isV6()) { + isc_throw(InvalidAddressFamily, "expected IPv6 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_PAGE6) .arg(page_size.page_size_) .arg(lower_bound_address.toText()); @@ -1550,6 +1571,13 @@ PgSqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, Lease6Collection PgSqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address, const asiolink::IOAddress& upper_bound_address) const { + // Expecting two IPv6 addresses. + if (!lower_bound_address.isV6() || !upper_bound_address.isV6()) { + isc_throw(InvalidAddressFamily, "expected two IPv6 addresses for " + "retrieving a range of leases, got " + << lower_bound_address << " and " << upper_bound_address); + } + if (upper_bound_address < lower_bound_address) { isc_throw(InvalidRange, "upper bound address " << upper_bound_address << " is lower than lower bound address " << lower_bound_address); diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc index da5eb4a7d7..289da233b2 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1304,6 +1305,10 @@ GenericLeaseMgrTest::testGetLeases4Paged() { // Zero page size is illegal too. EXPECT_THROW(lease_page_size.reset(new LeasePageSize(0)), OutOfRange); + + // Only IPv4 address can be used. + EXPECT_THROW(lmptr_->getLeases4(IOAddress("2001:db8::1"), LeasePageSize(3)), + InvalidAddressFamily); } void @@ -1342,6 +1347,13 @@ GenericLeaseMgrTest::testGetLeases4Range() { // Swapping the lower bound and upper bound should cause an error. EXPECT_THROW(lmptr_->getLeases4(IOAddress("192.0.2.8"), IOAddress("192.0.2.1")), InvalidRange); + + // Both must be IPv4 addresses. + EXPECT_THROW(lmptr_->getLeases4(IOAddress("192.0.2.3"), IOAddress("2001:db8::8")), + InvalidAddressFamily); + + EXPECT_THROW(lmptr_->getLeases4(IOAddress("2001:db8::2"), IOAddress("192.0.2.7")), + InvalidAddressFamily); } void @@ -1418,6 +1430,11 @@ GenericLeaseMgrTest::testGetLeases6Paged() { EXPECT_TRUE(found) << "lease for address " << lease->addr_.toText() << " was not returned in any of the pages"; } + + // Only IPv6 address can be used. + EXPECT_THROW(lmptr_->getLeases6(IOAddress("192.0.2.0"), LeasePageSize(3)), + InvalidAddressFamily); + } void @@ -1456,6 +1473,13 @@ GenericLeaseMgrTest::testGetLeases6Range() { // Swapping the lower bound and upper bound should cause an error. EXPECT_THROW(lmptr_->getLeases6(IOAddress("2001:db8::8"), IOAddress("2001:db8::1")), InvalidRange); + + // Both must be IPv6 addresses. + EXPECT_THROW(lmptr_->getLeases6(IOAddress("192.0.2.3"), IOAddress("2001:db8::8")), + InvalidAddressFamily); + + EXPECT_THROW(lmptr_->getLeases6(IOAddress("2001:db8::2"), IOAddress("192.0.2.7")), + InvalidAddressFamily); } void