Consume the preference before reading the locator in NID/L64/L32 tostruct

tostruct_nid() and tostruct_l64() read the 16-bit preference with the
non-consuming uint16_fromregion() and then memmove()'d the whole
remaining region -- still ten octets, still anchored at the preference
-- into the eight-octet nid[]/l64[] arrays. That folded the preference
into the first two locator octets and stored two octets past the end of
the array. tostruct_l32() shares the root cause: it read the 32-bit
locator from the same unconsumed offset, so the value was built from the
preference plus the first two locator octets.

Consume the two preference octets first, matching the sibling
tostruct_lp(), and assert the expected framing on the fixed-size types.

(cherry picked from commit 5aa279bbea)
This commit is contained in:
Ondřej Surý 2026-07-02 11:38:40 +02:00 committed by Ondřej Surý (GitLab job 7730831)
parent 73440816e4
commit 815587fbe6
3 changed files with 6 additions and 0 deletions

View file

@ -156,6 +156,8 @@ tostruct_l32(ARGS_TOSTRUCT) {
dns_rdata_toregion(rdata, &region);
l32->pref = uint16_fromregion(&region);
isc_region_consume(&region, 2);
INSIST(region.length == sizeof(l32->l32));
n = uint32_fromregion(&region);
l32->l32.s_addr = htonl(n);
return ISC_R_SUCCESS;

View file

@ -151,6 +151,8 @@ tostruct_l64(ARGS_TOSTRUCT) {
dns_rdata_toregion(rdata, &region);
l64->pref = uint16_fromregion(&region);
isc_region_consume(&region, 2);
INSIST(region.length == sizeof(l64->l64));
memmove(l64->l64, region.base, region.length);
return ISC_R_SUCCESS;
}

View file

@ -151,6 +151,8 @@ tostruct_nid(ARGS_TOSTRUCT) {
dns_rdata_toregion(rdata, &region);
nid->pref = uint16_fromregion(&region);
isc_region_consume(&region, 2);
INSIST(region.length == sizeof(nid->nid));
memmove(nid->nid, region.base, region.length);
return ISC_R_SUCCESS;
}