From: Shine <4c.fce2@proton.me> Date: Sun, 31 May 2026 13:16:09 +0000 (+0200) Subject: scripts: dhcp/dhcpv6: handling of invalid client ID values X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F23662%2Fhead;p=thirdparty%2Fopenwrt.git scripts: dhcp/dhcpv6: handling of invalid client ID values Verify and clean up client ID and global DUID config values before use, in order to prevent DHCP client malfunction and loss of IPv4 and/or IPv6 connectivity. - Accept common separators in the string (colon, dash, spaces/tabs, lf) - Ignore invalid values (non-hex or odd-numbered length) - Log a warning for invalid settings The fall back mechanism is as follows: If a (user-configured) network..clientid setting is found invalid, ignore and fall back to using network.globals.dhcp_default_duid. In case that's also invalid (e.g. has been tampered with), don't pass a client ID to updhc/odhcpc. In that case, udhcpc/odhcpc will use their defaults, which currently is the i/f MAC address resp. the i/f DUID-LL. Only error handling is introduced, no behavior change for valid settings. Signed-off-by: Shine <4c.fce2@proton.me> Link: https://github.com/openwrt/openwrt/pull/23662 Signed-off-by: Robert Marko --- diff --git a/package/base-files/files/lib/functions.sh b/package/base-files/files/lib/functions.sh index de19a5670bd..8adf1b8fb2c 100644 --- a/package/base-files/files/lib/functions.sh +++ b/package/base-files/files/lib/functions.sh @@ -16,6 +16,13 @@ NO_EXPORT=1 LOAD_STATE=1 LIST_SEP=" " +# check for valid hexdump and strip common separators and leading/trailing blanks +# input can be single- or multi-line, separators can be none, dash, colon or one or more spaces/tabs +hexdump_2hex() { + [ -z "$1" ] && return + echo -n "$1" | tr '\nA-F' ' a-f' | sed -nr '/^\s*[0-9a-f]{2}((\s+|[:-]?)[0-9a-f]{2})*\s*$/s/[[:space:]:-]*//pg' +} + # xor multiple hex values of the same length xor() { local val diff --git a/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh index e5724ff11f7..2214fc0b8da 100755 --- a/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh +++ b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh @@ -40,9 +40,14 @@ proto_dhcp_get_default_clientid() { local duid local iaid - network_generate_iface_iaid iaid "$iface" duid="$(uci_get network @globals[0] dhcp_default_duid)" - [ -n "$duid" ] && printf "ff%s%s" "$iaid" "$duid" + [ -n "$duid" ] && { + duid="$(hexdump_2hex "$duid")" + [ -z "$duid" ] && logger -p warn -t dhcp "$iface: ignoring invalid dhcp_default_duid value" + } + [ -z "$duid" ] && return + network_generate_iface_iaid iaid "$iface" + printf "ff%s%s" "$iaid" "$duid" } proto_dhcp_setup() { @@ -65,8 +70,12 @@ proto_dhcp_setup() { [ "$defaultreqopts" = 0 ] && defaultreqopts="-o" || defaultreqopts= [ "$broadcast" = 1 ] && broadcast="-B" || broadcast= [ "$norelease" = 1 ] && norelease="" || norelease="-R" + [ -n "$clientid" ] && { + clientid="$(hexdump_2hex "$clientid")" + [ -z "$clientid" ] && logger -p warn -t dhcp "$iface: ignoring invalid clientid value" + } [ -z "$clientid" ] && clientid="$(proto_dhcp_get_default_clientid "$iface")" - [ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" + [ -n "$clientid" ] && clientid="-x 0x3d:$clientid" [ -n "$vendorid" ] && append dhcpopts "-x 0x3c:$(echo -n "$vendorid" | hexdump -ve '1/1 "%02x"')" [ -n "$iface6rd" ] && proto_export "IFACE6RD=$iface6rd" [ "$iface6rd" != 0 -a -f /lib/netifd/proto/6rd.sh ] && append dhcpopts "-O 212" diff --git a/package/network/ipv6/odhcp6c/files/dhcpv6.sh b/package/network/ipv6/odhcp6c/files/dhcpv6.sh index 70d23dd936f..6e257e11cbe 100755 --- a/package/network/ipv6/odhcp6c/files/dhcpv6.sh +++ b/package/network/ipv6/odhcp6c/files/dhcpv6.sh @@ -87,7 +87,15 @@ proto_dhcpv6_setup() { [ -z "$reqprefix" -o "$reqprefix" = "auto" ] && reqprefix=0 [ "$reqprefix" != "no" ] && append opts "-P$reqprefix" + [ -n "$clientid" ] && { + clientid="$(hexdump_2hex "$clientid")" + [ -z "$clientid" ] && logger -p warn -t dhcpv6 "$iface: ignoring invalid clientid value" + } [ -z "$clientid" ] && clientid="$(uci_get network @globals[0] dhcp_default_duid)" + [ -n "$clientid" ] && { + clientid="$(hexdump_2hex "$clientid")" + [ -z "$clientid" ] && logger -p warn -t dhcpv6 "$iface: ignoring invalid dhcp_default_duid value" + } [ -n "$clientid" ] && append opts "-c$clientid" [ "$defaultreqopts" = "0" ] && append opts "-R"