Fix bogus 256-byte DHCPv6 vendor-class option.

lookup_dhcp_len() returns the flag word from the option table, so
since 1af6ee6468 an option carrying
OT_DHCP6_VENDOR yields an opt_len of 0x0100.

--dhcp-option=option6:vendor-class,343 has a purely decimal argument
list and therefore takes the is_dec branch, which comes long before
the new OT_DHCP6_VENDOR branch, and

  if (opt_len != 0)
    new->len = opt_len;

sets new->len to 256. The value is then written by shifting an int by
up to 2040 bits, which is undefined behavior, and a 256-byte
vendor-class option ends up on the wire:

  $ dnsmasq --test --dhcp-option=option6:vendor-class,343
  option.c:1715:23: runtime error: shift exponent 2040 is too large
  for 32-bit type 'int'
  dnsmasq: syntax check OK.

The numeric spelling option6:16,343 takes the same path. Before
1af6ee6 both were rejected, as vendor-class was OT_INTERNAL back then.

Keep the is_dec branch away from OT_DHCP6_VENDOR, so the dedicated
parser runs and reports the missing vendor class instead.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER authored and Simon Kelley committed 2026-08-16 21:10:45 +01:00
1 parent 0a31ade4db
commit 4388c38468
1 file changed
+1 -1
+1 -1
View File
@@ -1688,7 +1688,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
parse_hex(comma, new->val, digs, (flags & DHOPT_MATCH) ? &new->u.wildcard_mask : NULL, NULL);
new->flags |= DHOPT_HEX;
}
else if (is_dec)
else if (is_dec && !(opt_len & OT_DHCP6_VENDOR))
{
int i, val = atoi(comma);
/* assume numeric arg is 1 byte except for