- My goal is:
- Preventing invalid mDNS text records.
- My actions are:
mgos_dns_sd_add_service_instancewith a set of key/value pairs that are more than 256 bytes.
- The result I see is:
- A text record without a null terminator.
- My expectation & question is:
- A valid DNS record with a null terminator.
The code in question is here: https://github.com/mongoose-os-libs/dns-sd/blob/master/src/mongoose/mgos_dns_sd.c#L425
For an example, let’s assume there’s already 250 bytes of data in the buffer. This means that
p = buf + 250. On the next execution of the loop, we calculate
p = 256 - (250) - 1 = 5. Since this is positive, we pass the check on line 427 and do not break out of the loop. We then call
snprintf with the destination set to
p + 1 == buf. We can rely on
snprintf to keep things within the 5 bytes we allow but this means we’re printing to
buf. However, this means that the last byte of the buffer is not
buf is then passed into
mg_mk_str_n with the size as
p - buf (in this example, it would be equal to 256), it should be OK. But it’s then passed into
mg_strdup. You can see the source for that here: https://github.com/cesanta/mjs/blob/master/common/mg_str.c#L78. It is just a wrapper for
mg_strdup_common (see https://github.com/cesanta/mjs/blob/master/common/mg_str.c#L61) with the
nul_terminate parameter fixed to 0. This means it only allocates
N bytes rather than
N + 1.
Since it is possible to use the entire buffer,
mg_strdup_nul should be called instead.