diff options
| author | Mark Stapp <mjs@voltanet.io> | 2021-03-01 15:41:30 -0500 | 
|---|---|---|
| committer | Mark Stapp <mjs@voltanet.io> | 2021-03-01 15:41:30 -0500 | 
| commit | 8e2c653ed30f672617ef97f4479aff24db855154 (patch) | |
| tree | f53a4d41bb799360edbd2bcd757146abd9ce35c4 /lib | |
| parent | 001ab42b1916e7ad69b77a7defdfd5e728104688 (diff) | |
lib: protect printfrr extensions from NULL input
Protect the lib printfrr extension handlers from NULL inputs.
Signed-off-by: Mark Stapp <mjs@voltanet.io>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/prefix.c | 54 | ||||
| -rw-r--r-- | lib/sockunion.c | 59 | ||||
| -rw-r--r-- | lib/srcdest_table.c | 9 | 
3 files changed, 79 insertions, 43 deletions
diff --git a/lib/prefix.c b/lib/prefix.c index c98e0c1c72..5e5c2d89a8 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1366,7 +1366,11 @@ static ssize_t printfrr_ea(char *buf, size_t bsz, const char *fmt,  {  	const struct ethaddr *mac = ptr; -	prefix_mac2str(mac, buf, bsz); +	if (mac) +		prefix_mac2str(mac, buf, bsz); +	else +		strlcpy(buf, "NULL", bsz); +  	return 2;  } @@ -1376,7 +1380,11 @@ static ssize_t printfrr_ia(char *buf, size_t bsz, const char *fmt,  {  	const struct ipaddr *ipa = ptr; -	ipaddr2str(ipa, buf, bsz); +	if (ipa) +		ipaddr2str(ipa, buf, bsz); +	else +		strlcpy(buf, "NULL", bsz); +  	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,  			   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;  } @@ -1392,7 +1404,11 @@ printfrr_ext_autoreg_p("I6", printfrr_i6)  static ssize_t printfrr_i6(char *buf, size_t bsz, const char *fmt,  			   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;  } @@ -1400,7 +1416,11 @@ printfrr_ext_autoreg_p("FX", printfrr_pfx)  static ssize_t printfrr_pfx(char *buf, size_t bsz, const char *fmt,  			    int prec, const void *ptr)  { -	prefix2str(ptr, buf, bsz); +	if (ptr) +		prefix2str(ptr, buf, bsz); +	else +		strlcpy(buf, "NULL", bsz); +  	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;  	struct fbuf fb = { .buf = buf, .pos = buf, .len = bsz - 1 }; -	if (sg->src.s_addr == INADDR_ANY) -		bprintfrr(&fb, "(*,"); -	else -		bprintfrr(&fb, "(%pI4,", &sg->src); +	if (sg) { +		if (sg->src.s_addr == INADDR_ANY) +			bprintfrr(&fb, "(*,"); +		else +			bprintfrr(&fb, "(%pI4,", &sg->src); -	if (sg->grp.s_addr == INADDR_ANY) -		bprintfrr(&fb, "*)"); -	else -		bprintfrr(&fb, "%pI4)", &sg->grp); +		if (sg->grp.s_addr == INADDR_ANY) +			bprintfrr(&fb, "*)"); +		else +			bprintfrr(&fb, "%pI4)", &sg->grp); + +		fb.pos[0] = '\0'; + +	} else { +		strlcpy(buf, "NULL", bsz); +	} -	fb.pos[0] = '\0';  	return 3;  } diff --git a/lib/sockunion.c b/lib/sockunion.c index 1dbf77efa4..c701da1e03 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -673,39 +673,44 @@ static ssize_t printfrr_psu(char *buf, size_t bsz, const char *fmt,  	bool endflags = false;  	ssize_t consumed = 2; -	while (!endflags) { -		switch (fmt[consumed++]) { -		case 'p': -			include_port = true; +	if (su) { +		while (!endflags) { +			switch (fmt[consumed++]) { +			case 'p': +				include_port = true; +				break; +			default: +				consumed--; +				endflags = true; +				break; +			} +		}; + +		switch (sockunion_family(su)) { +		case AF_UNSPEC: +			bprintfrr(&fb, "(unspec)");  			break; -		default: -			consumed--; -			endflags = true; +		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));  		} -	}; -	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; -	default: -		bprintfrr(&fb, "(af %d)", sockunion_family(su)); +		fb.pos[0] = '\0'; +	} else { +		strlcpy(buf, "NULL", bsz);  	} -	fb.pos[0] = '\0';  	return consumed;  } diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c index 8ffa0e9709..ef82b7ac01 100644 --- a/lib/srcdest_table.c +++ b/lib/srcdest_table.c @@ -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 prefix *dst_p, *src_p; -	srcdest_rnode_prefixes(rn, &dst_p, &src_p); -	srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, buf, bsz); +	if (rn) { +		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;  }  | 
