From e3a0d181a279334c7d7a10c5b09fd1610384101c Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Wed, 3 Sep 2025 12:52:51 -0700 Subject: [PATCH] d2/dhcp[46]/radius/dhcpsrv: Avoid Boost lexical_cast on enums MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clang with libc++ hardening (-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST) rejects Boost's enum trait probe used by `boost::lexical_cast`: `boost::type_traits::is_signed/is_unsigned` defines `static const T minus_one = (T)-1;`, which is ill-formed for scoped/limited enums whose valid range does not include −1 (e.g. enums with values [0..3]). When an enum is passed to `lexical_cast`, this triggers errors like: error: in-class initializer for static data member is not a constant expression ... minus_one = (static_cast(-1)); In Kea this surfaced via logging `.arg(enum_value)` and when writing `Lease6::type_` to CSV. This change makes all such call sites avoid `lexical_cast` on enums: * d2 transactions (`check_exists_*`, `nc_*`, `simple_*`): cast `getDnsUpdateStatus()` to `int` before passing to `.arg(...)`. * d2 queue manager (`d2_queue_mgr.cc`): cast `mgr_state_` to `int` before logging. * DHCPv4/6 servers (`dhcp4_srv.cc`, `dhcp6_srv.cc`): cast `dhcp_ddns::NameChangeSender::Result` to `int` before logging. * RADIUS hook (`radius_accounting.cc`): cast `env.event_` to `int` for the numeric field; we still log the textual form via `eventToText(event_)` in the next argument. * DHCPv6 CSV writer (`csv_lease_file6.cc`): write `lease_type` using `isc::dhcp::Lease::typeToText(lease.type_)` instead of passing the enum directly. This is human-readable and uses Kea’s own canonical stringifier, while avoiding the Boost enum path entirely. why: - Prevents Boost from instantiating enum trait checks that cast −1 to an enum. - Unblocks builds with recent Clang/libc++ hardening. - Keeps log output stable (numeric codes retained) and improves CSV clarity for lease type by using the provided textual converter. No functional/ABI changes; only formatting of certain log/CSV values. If a downstream consumer expects a numeric `lease_type`, it can be adjusted to parse the textual value or the change can be trivially flipped to `static_cast(lease.type_)`. Upstream-Status: Submitted [https://gitlab.isc.org/isc-projects/kea/-/issues/4100] Signed-off-by: Khem Raj --- src/bin/d2/check_exists_add.cc | 6 +++--- src/bin/d2/check_exists_remove.cc | 6 +++--- src/bin/d2/d2_queue_mgr.cc | 2 +- src/bin/d2/nc_add.cc | 6 +++--- src/bin/d2/nc_remove.cc | 6 +++--- src/bin/d2/simple_add.cc | 4 ++-- src/bin/d2/simple_add_without_dhcid.cc | 4 ++-- src/bin/d2/simple_remove.cc | 4 ++-- src/bin/d2/simple_remove_without_dhcid.cc | 4 ++-- src/bin/dhcp4/dhcp4_srv.cc | 2 +- src/bin/dhcp6/dhcp6_srv.cc | 2 +- src/hooks/dhcp/radius/radius_accounting.cc | 2 +- src/lib/dhcpsrv/csv_lease_file6.cc | 2 +- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/bin/d2/check_exists_add.cc b/src/bin/d2/check_exists_add.cc index 11bb29f..edfef31 100644 --- a/src/bin/d2/check_exists_add.cc +++ b/src/bin/d2/check_exists_add.cc @@ -270,7 +270,7 @@ CheckExistsAddTransaction::addingFwdAddrsHandler() { // bigger is wrong. LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_ADD_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -397,7 +397,7 @@ CheckExistsAddTransaction::replacingFwdAddrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REPLACE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -541,7 +541,7 @@ CheckExistsAddTransaction::replacingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REPLACE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/d2/check_exists_remove.cc b/src/bin/d2/check_exists_remove.cc index 8ae5296..8b6b221 100644 --- a/src/bin/d2/check_exists_remove.cc +++ b/src/bin/d2/check_exists_remove.cc @@ -268,7 +268,7 @@ CheckExistsRemoveTransaction::removingFwdAddrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REMOVE_ADDRS_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -404,7 +404,7 @@ CheckExistsRemoveTransaction::removingFwdRRsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REMOVE_RRS_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -556,7 +556,7 @@ CheckExistsRemoveTransaction::removingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REMOVE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/d2/d2_queue_mgr.cc b/src/bin/d2/d2_queue_mgr.cc index f902b22..effa56b 100644 --- a/src/bin/d2/d2_queue_mgr.cc +++ b/src/bin/d2/d2_queue_mgr.cc @@ -78,7 +78,7 @@ D2QueueMgr::operator()(const dhcp_ddns::NameChangeListener::Result result, // this is unexpected so we will treat it as a receive error. // This is most likely an unforeseen programmatic issue. LOG_ERROR(dhcp_to_d2_logger, DHCP_DDNS_QUEUE_MGR_UNEXPECTED_STOP) - .arg(mgr_state_); + .arg(static_cast(mgr_state_)); stopListening(STOPPED_RECV_ERROR); } diff --git a/src/bin/d2/nc_add.cc b/src/bin/d2/nc_add.cc index 7bffc16..1d17bb2 100644 --- a/src/bin/d2/nc_add.cc +++ b/src/bin/d2/nc_add.cc @@ -272,7 +272,7 @@ NameAddTransaction::addingFwdAddrsHandler() { // bigger is wrong. LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_ADD_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -399,7 +399,7 @@ NameAddTransaction::replacingFwdAddrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REPLACE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -542,7 +542,7 @@ NameAddTransaction::replacingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REPLACE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/d2/nc_remove.cc b/src/bin/d2/nc_remove.cc index 874e43b..182343c 100644 --- a/src/bin/d2/nc_remove.cc +++ b/src/bin/d2/nc_remove.cc @@ -268,7 +268,7 @@ NameRemoveTransaction::removingFwdAddrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REMOVE_ADDRS_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -404,7 +404,7 @@ NameRemoveTransaction::removingFwdRRsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REMOVE_RRS_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -555,7 +555,7 @@ NameRemoveTransaction::removingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REMOVE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/d2/simple_add.cc b/src/bin/d2/simple_add.cc index 6113b4d..73aa5b4 100644 --- a/src/bin/d2/simple_add.cc +++ b/src/bin/d2/simple_add.cc @@ -259,7 +259,7 @@ SimpleAddTransaction::replacingFwdAddrsHandler() { // bigger is wrong. LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_ADD_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -404,7 +404,7 @@ SimpleAddTransaction::replacingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REPLACE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/d2/simple_add_without_dhcid.cc b/src/bin/d2/simple_add_without_dhcid.cc index ccea83a..97918ad 100644 --- a/src/bin/d2/simple_add_without_dhcid.cc +++ b/src/bin/d2/simple_add_without_dhcid.cc @@ -260,7 +260,7 @@ SimpleAddWithoutDHCIDTransaction::replacingFwdAddrsHandler() { // bigger is wrong. LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_ADD_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -406,7 +406,7 @@ SimpleAddWithoutDHCIDTransaction::replacingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REPLACE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/d2/simple_remove.cc b/src/bin/d2/simple_remove.cc index e1d9a78..14f416b 100644 --- a/src/bin/d2/simple_remove.cc +++ b/src/bin/d2/simple_remove.cc @@ -272,7 +272,7 @@ SimpleRemoveTransaction::removingFwdRRsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REMOVE_RRS_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -423,7 +423,7 @@ SimpleRemoveTransaction::removingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REMOVE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/d2/simple_remove_without_dhcid.cc b/src/bin/d2/simple_remove_without_dhcid.cc index 04fe4df..cefdda8 100644 --- a/src/bin/d2/simple_remove_without_dhcid.cc +++ b/src/bin/d2/simple_remove_without_dhcid.cc @@ -273,7 +273,7 @@ SimpleRemoveWithoutDHCIDTransaction::removingFwdRRsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_FORWARD_REMOVE_RRS_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); @@ -425,7 +425,7 @@ SimpleRemoveWithoutDHCIDTransaction::removingRevPtrsHandler() { LOG_ERROR(d2_to_dns_logger, DHCP_DDNS_REVERSE_REMOVE_BAD_DNSCLIENT_STATUS) .arg(getRequestId()) - .arg(getDnsUpdateStatus()) + .arg(static_cast(getDnsUpdateStatus())) .arg(getNcr()->getFqdn()) .arg(getCurrentServer()->toText()); diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 0701ed4..471e94c 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -5101,7 +5101,7 @@ Dhcpv4Srv::d2ClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr& ncr) { LOG_ERROR(ddns4_logger, DHCP4_DDNS_REQUEST_SEND_FAILED). - arg(result).arg((ncr ? ncr->toText() : " NULL ")); + arg(static_cast(result)).arg((ncr ? ncr->toText() : " NULL ")); // We cannot communicate with kea-dhcp-ddns, suspend further updates. /// @todo We may wish to revisit this, but for now we will simply turn /// them off. diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 417960b..818046d 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -5054,7 +5054,7 @@ Dhcpv6Srv::d2ClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr& ncr) { LOG_ERROR(ddns6_logger, DHCP6_DDNS_REQUEST_SEND_FAILED). - arg(result).arg((ncr ? ncr->toText() : " NULL ")); + arg(static_cast(result)).arg((ncr ? ncr->toText() : " NULL ")); // We cannot communicate with kea-dhcp-ddns, suspend further updates. /// @todo We may wish to revisit this, but for now we will simply turn /// them off. diff --git a/src/hooks/dhcp/radius/radius_accounting.cc b/src/hooks/dhcp/radius/radius_accounting.cc index 30eb07e..31f6d5e 100644 --- a/src/hooks/dhcp/radius/radius_accounting.cc +++ b/src/hooks/dhcp/radius/radius_accounting.cc @@ -760,7 +760,7 @@ RadiusAccounting::terminate(RadiusAcctEnv env, int result) { if (result != OK_RC) { LOG_ERROR(radius_logger, RADIUS_ACCOUNTING_ERROR) .arg(env.session_id_) - .arg(env.event_) + .arg(static_cast(env.event_)) .arg(eventToText(env.event_)) .arg(result) .arg(exchangeRCtoText(result)); diff --git a/src/lib/dhcpsrv/csv_lease_file6.cc b/src/lib/dhcpsrv/csv_lease_file6.cc index 830d2e5..a899aef 100644 --- a/src/lib/dhcpsrv/csv_lease_file6.cc +++ b/src/lib/dhcpsrv/csv_lease_file6.cc @@ -51,7 +51,7 @@ CSVLeaseFile6::append(const Lease6& lease) { row.writeAt(getColumnIndex("expire"), static_cast(lease.cltt_) + lease.valid_lft_); row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_); row.writeAt(getColumnIndex("pref_lifetime"), lease.preferred_lft_); - row.writeAt(getColumnIndex("lease_type"), lease.type_); + row.writeAt(getColumnIndex("lease_type"), isc::dhcp::Lease::typeToText(lease.type_)); row.writeAt(getColumnIndex("iaid"), lease.iaid_); row.writeAt(getColumnIndex("prefix_len"), static_cast(lease.prefixlen_));