Skip to content

Commit 13cec01

Browse files
committed
dhcpv6-ia: dhcpv6_log_ia_addr(): parse return of snprintf
snprintf() returns also in the failure case how many characters would have been required to print the full string. Check return of snprintf() and ensure the log_ctxt->buf_idx never points outside of the given log_ctxt->buf. Fixes: TOB-OWRT-5 Reported-by: Trail of Bits Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
1 parent 13ef483 commit 13cec01

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

src/dhcpv6-ia.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ static size_t build_ia(uint8_t *buf, size_t buflen, uint16_t status,
824824
struct log_ctxt {
825825
char *buf;
826826
int buf_len;
827+
/* if full, buf_idx will point to the last valid memory in buf */
827828
int buf_idx;
828829
};
829830

@@ -832,10 +833,20 @@ static void dhcpv6_log_ia_addr(_o_unused struct dhcpv6_lease *lease, struct in6_
832833
{
833834
struct log_ctxt *ctxt = (struct log_ctxt *)arg;
834835
char addrbuf[INET6_ADDRSTRLEN];
836+
int ret;
837+
838+
/* Log buffer full */
839+
if (ctxt->buf_idx >= ctxt->buf_len - 1)
840+
return;
835841

836842
inet_ntop(AF_INET6, addr, addrbuf, sizeof(addrbuf));
837-
ctxt->buf_idx += snprintf(ctxt->buf + ctxt->buf_idx, ctxt->buf_len - ctxt->buf_idx,
838-
" %s/%" PRIu8, addrbuf, prefix_len);
843+
ret = snprintf(ctxt->buf + ctxt->buf_idx, ctxt->buf_len - ctxt->buf_idx,
844+
" %s/%" PRIu8, addrbuf, prefix_len);
845+
846+
if (ret + ctxt->buf_idx < ctxt->buf_len - 1)
847+
ctxt->buf_idx += ret;
848+
else
849+
ctxt->buf_idx = ctxt->buf_len - 1;
839850
}
840851

841852
static void dhcpv6_log(uint8_t msgtype, struct interface *iface, time_t now,

0 commit comments

Comments
 (0)