DHCP decoder handling of header string fields
Alan DeKok
aland at deployingradius.com
Fri Feb 5 00:01:51 CET 2016
On Feb 4, 2016, at 11:21 AM, Chaigneau, Nicolas <nicolas.chaigneau at capgemini.com> wrote
> I've noticed that FreeRADIUS DHCP decoder is handling strings from the DHCP header fields a bit oddly.
>
> Basically, it allocates a value pair buffer with the maximum field length (64 or 128 octets, for DHCP-Server-Host-Name and DHCP-Boot-Filename respectively) + 1, and memcpy the data then add a '\0'.
That's not good.
> But RFC 2131 explicitly states that these DHCP fields are null terminated strings. So why not handle them as such ?
It should.
> Current code from "fr_dhcp_decode" function:
>
> case PW_TYPE_STRING:
> q = talloc_array(vp, char, dhcp_header_sizes[i] + 1);
> memcpy(q, p, dhcp_header_sizes[i]);
> q[dhcp_header_sizes[i]] = '\0';
> fr_pair_value_strsteal(vp, q);
>
> if (vp->vp_length == 0) fr_pair_list_free(&vp);
> break;
That's inefficient for a whole host of reasons.
> How about something like this instead ? (copy a string, but do not trust the DHCP field to be actually null terminated)
>
> case PW_TYPE_STRING:
> if (*p != '\0') {
> uint8_t *end;
> int len;
> end = memchr(p, '\0', dhcp_header_sizes[i]);
> len = end ? end - p : dhcp_header_sizes[i];
> q = talloc_array(vp, char, len + 1);
> memcpy(q, p, len);
> q[len] = '\0';
> fr_pair_value_strsteal(vp, q);
> }
> if (vp->vp_length == 0) fr_pair_list_free(&vp);
That should work. Though the check for a vp_length == 0 should really be done before allocating any memory.
> This would avoid having things like:
>
> DHCP-Server-Host-Name = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
> DHCP-Boot-Filename = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
That's good.
> (I can do a pull request for 3.1.x if you wish)
That would be good. It should also be applied to 3.0.
Alan DeKok.
More information about the Freeradius-Devel
mailing list