lib: protect printfrr extensions from NULL input

Protect the lib printfrr extension handlers from NULL inputs.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
Mark Stapp 2021-03-01 15:41:30 -05:00
parent 001ab42b19
commit 8e2c653ed3
3 changed files with 79 additions and 43 deletions

View File

@ -1366,7 +1366,11 @@ static ssize_t printfrr_ea(char *buf, size_t bsz, const char *fmt,
{ {
const struct ethaddr *mac = ptr; const struct ethaddr *mac = ptr;
prefix_mac2str(mac, buf, bsz); if (mac)
prefix_mac2str(mac, buf, bsz);
else
strlcpy(buf, "NULL", bsz);
return 2; return 2;
} }
@ -1376,7 +1380,11 @@ static ssize_t printfrr_ia(char *buf, size_t bsz, const char *fmt,
{ {
const struct ipaddr *ipa = ptr; const struct ipaddr *ipa = ptr;
ipaddr2str(ipa, buf, bsz); if (ipa)
ipaddr2str(ipa, buf, bsz);
else
strlcpy(buf, "NULL", bsz);
return 2; return 2;
} }
@ -1384,7 +1392,11 @@ printfrr_ext_autoreg_p("I4", printfrr_i4)
static ssize_t printfrr_i4(char *buf, size_t bsz, const char *fmt, static ssize_t printfrr_i4(char *buf, size_t bsz, const char *fmt,
int prec, const void *ptr) int prec, const void *ptr)
{ {
inet_ntop(AF_INET, ptr, buf, bsz); if (ptr)
inet_ntop(AF_INET, ptr, buf, bsz);
else
strlcpy(buf, "NULL", bsz);
return 2; return 2;
} }
@ -1392,7 +1404,11 @@ printfrr_ext_autoreg_p("I6", printfrr_i6)
static ssize_t printfrr_i6(char *buf, size_t bsz, const char *fmt, static ssize_t printfrr_i6(char *buf, size_t bsz, const char *fmt,
int prec, const void *ptr) int prec, const void *ptr)
{ {
inet_ntop(AF_INET6, ptr, buf, bsz); if (ptr)
inet_ntop(AF_INET6, ptr, buf, bsz);
else
strlcpy(buf, "NULL", bsz);
return 2; return 2;
} }
@ -1400,7 +1416,11 @@ printfrr_ext_autoreg_p("FX", printfrr_pfx)
static ssize_t printfrr_pfx(char *buf, size_t bsz, const char *fmt, static ssize_t printfrr_pfx(char *buf, size_t bsz, const char *fmt,
int prec, const void *ptr) int prec, const void *ptr)
{ {
prefix2str(ptr, buf, bsz); if (ptr)
prefix2str(ptr, buf, bsz);
else
strlcpy(buf, "NULL", bsz);
return 2; return 2;
} }
@ -1411,16 +1431,22 @@ static ssize_t printfrr_psg(char *buf, size_t bsz, const char *fmt,
const struct prefix_sg *sg = ptr; const struct prefix_sg *sg = ptr;
struct fbuf fb = { .buf = buf, .pos = buf, .len = bsz - 1 }; struct fbuf fb = { .buf = buf, .pos = buf, .len = bsz - 1 };
if (sg->src.s_addr == INADDR_ANY) if (sg) {
bprintfrr(&fb, "(*,"); if (sg->src.s_addr == INADDR_ANY)
else bprintfrr(&fb, "(*,");
bprintfrr(&fb, "(%pI4,", &sg->src); else
bprintfrr(&fb, "(%pI4,", &sg->src);
if (sg->grp.s_addr == INADDR_ANY) if (sg->grp.s_addr == INADDR_ANY)
bprintfrr(&fb, "*)"); bprintfrr(&fb, "*)");
else else
bprintfrr(&fb, "%pI4)", &sg->grp); bprintfrr(&fb, "%pI4)", &sg->grp);
fb.pos[0] = '\0';
} else {
strlcpy(buf, "NULL", bsz);
}
fb.pos[0] = '\0';
return 3; return 3;
} }

View File

@ -673,39 +673,44 @@ static ssize_t printfrr_psu(char *buf, size_t bsz, const char *fmt,
bool endflags = false; bool endflags = false;
ssize_t consumed = 2; ssize_t consumed = 2;
while (!endflags) { if (su) {
switch (fmt[consumed++]) { while (!endflags) {
case 'p': switch (fmt[consumed++]) {
include_port = true; case 'p':
include_port = true;
break;
default:
consumed--;
endflags = true;
break;
}
};
switch (sockunion_family(su)) {
case AF_UNSPEC:
bprintfrr(&fb, "(unspec)");
break;
case AF_INET:
inet_ntop(AF_INET, &su->sin.sin_addr, buf, bsz);
fb.pos += strlen(fb.buf);
if (include_port)
bprintfrr(&fb, ":%d", su->sin.sin_port);
break;
case AF_INET6:
inet_ntop(AF_INET6, &su->sin6.sin6_addr, buf, bsz);
fb.pos += strlen(fb.buf);
if (include_port)
bprintfrr(&fb, ":%d", su->sin6.sin6_port);
break; break;
default: default:
consumed--; bprintfrr(&fb, "(af %d)", sockunion_family(su));
endflags = true;
break;
} }
};
switch (sockunion_family(su)) { fb.pos[0] = '\0';
case AF_UNSPEC: } else {
bprintfrr(&fb, "(unspec)"); strlcpy(buf, "NULL", bsz);
break;
case AF_INET:
inet_ntop(AF_INET, &su->sin.sin_addr, buf, bsz);
fb.pos += strlen(fb.buf);
if (include_port)
bprintfrr(&fb, ":%d", su->sin.sin_port);
break;
case AF_INET6:
inet_ntop(AF_INET6, &su->sin6.sin6_addr, buf, bsz);
fb.pos += strlen(fb.buf);
if (include_port)
bprintfrr(&fb, ":%d", su->sin6.sin6_port);
break;
default:
bprintfrr(&fb, "(af %d)", sockunion_family(su));
} }
fb.pos[0] = '\0';
return consumed; return consumed;
} }

View File

@ -313,8 +313,13 @@ static ssize_t printfrr_rn(char *buf, size_t bsz, const char *fmt,
const struct route_node *rn = ptr; const struct route_node *rn = ptr;
const struct prefix *dst_p, *src_p; const struct prefix *dst_p, *src_p;
srcdest_rnode_prefixes(rn, &dst_p, &src_p); if (rn) {
srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, buf, bsz); srcdest_rnode_prefixes(rn, &dst_p, &src_p);
srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, buf, bsz);
} else {
strlcpy(buf, "NULL", bsz);
}
return 2; return 2;
} }