]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
scripts: dhcp/dhcpv6: handling of invalid client ID values 23662/head
authorShine <4c.fce2@proton.me>
Sun, 31 May 2026 13:16:09 +0000 (15:16 +0200)
committerRobert Marko <robimarko@gmail.com>
Thu, 11 Jun 2026 08:40:57 +0000 (10:40 +0200)
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.<ifname>.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 <robimarko@gmail.com>
package/base-files/files/lib/functions.sh
package/network/config/netifd/files/lib/netifd/proto/dhcp.sh
package/network/ipv6/odhcp6c/files/dhcpv6.sh

index de19a5670bdb316d38b339c8edf0ae2b43d9e9d1..8adf1b8fb2c0022cd76041c195c5663c4a451a73 100644 (file)
@@ -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
index e5724ff11f7f3f18840b854ca87cdf3412b761dc..2214fc0b8dad85cb00e7bc5237fb24b69952edda 100755 (executable)
@@ -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"
index 70d23dd936f55164256c84cdfcebf9f85edaad59..6e257e11cbe76f9f35de365a88202d72c1eaa7e2 100755 (executable)
@@ -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"