From 7524a0790d23f2ecfad3e98c058f58d7dc01a655 Mon Sep 17 00:00:00 2001
From: Kris Kennaway <kris@FreeBSD.org>
Date: Thu, 5 Oct 2000 02:49:49 +0000
Subject: [PATCH] * Buffer-safe string function cleanup. There are a couple of
 strcpy()   and strcat()s which would be more difficult to fix, but I think
 they're   safe anyway. * Don't crash at runtime by overflowing a buffer with
 constant data in   print-icmp.c on a long hostname. * Don't overflow a static
 buffer by trying to decode an AFS ACL into a buffer   which is way too small
 for it.

Reviewed by:    -audit
---
 contrib/tcpdump/addrtoname.c   |  6 +++---
 contrib/tcpdump/print-atalk.c  |  4 ++--
 contrib/tcpdump/print-fr.c     |  6 ++++--
 contrib/tcpdump/print-icmp.c   | 38 +++++++++++++++++-----------------
 contrib/tcpdump/print-sunrpc.c |  6 ++++--
 5 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c
index 99134e94cb6a..c1f220821c08 100644
--- a/contrib/tcpdump/addrtoname.c
+++ b/contrib/tcpdump/addrtoname.c
@@ -559,7 +559,7 @@ tcpport_string(u_short port)
 	tp->addr = i;
 	tp->nxt = newhnamemem();
 
-	(void)sprintf(buf, "%u", i);
+	(void)snprintf(buf, sizeof(buf), "%u", i);
 	tp->name = savestr(buf);
 	return (tp->name);
 }
@@ -578,7 +578,7 @@ udpport_string(register u_short port)
 	tp->addr = i;
 	tp->nxt = newhnamemem();
 
-	(void)sprintf(buf, "%u", i);
+	(void)snprintf(buf, sizeof(buf), "%u", i);
 	tp->name = savestr(buf);
 	return (tp->name);
 }
@@ -604,7 +604,7 @@ init_servarray(void)
 		while (table->name)
 			table = table->nxt;
 		if (nflag) {
-			(void)sprintf(buf, "%d", port);
+			(void)snprintf(buf, sizeof(buf), "%d", port);
 			table->name = savestr(buf);
 		} else
 			table->name = savestr(sv->s_name);
diff --git a/contrib/tcpdump/print-atalk.c b/contrib/tcpdump/print-atalk.c
index 869881fa014f..2b77ecd35579 100644
--- a/contrib/tcpdump/print-atalk.c
+++ b/contrib/tcpdump/print-atalk.c
@@ -500,7 +500,7 @@ ataddr_string(u_short atnet, u_char athost)
 {
 	register struct hnamemem *tp, *tp2;
 	register int i = (atnet << 8) | athost;
-	char nambuf[256];
+	char nambuf[MAXHOSTNAMELEN + 20];
 	static int first = 1;
 	FILE *fp;
 
@@ -545,7 +545,7 @@ ataddr_string(u_short atnet, u_char athost)
 		if (tp2->addr == i) {
 			tp->addr = (atnet << 8) | athost;
 			tp->nxt = newhnamemem();
-			(void)sprintf(nambuf, "%s.%d", tp2->name, athost);
+			(void)snprintf(nambuf, sizeof(nambuf), "%s.%d", tp2->name, athost);
 			tp->name = savestr(nambuf);
 			return (tp->name);
 		}
diff --git a/contrib/tcpdump/print-fr.c b/contrib/tcpdump/print-fr.c
index 80364d3a12ea..70393387f210 100644
--- a/contrib/tcpdump/print-fr.c
+++ b/contrib/tcpdump/print-fr.c
@@ -17,6 +17,8 @@
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
  */
 
 #ifndef lint
@@ -395,12 +397,12 @@ q933_print(const u_char *p, int length)
 		    break;
 		case LINK_VERIFY_IE_91:
 		case LINK_VERIFY_IE_94:
-		    sprintf(temp_str,"TX Seq: %3d, RX Seq: %3d",
+		    snprintf(temp_str, sizeof(temp_str), "TX Seq: %3d, RX Seq: %3d",
 			    ptemp[2], ptemp[3]);
 		    decode_str = temp_str;
 		    break;
 		case PVC_STATUS_IE:
-		    sprintf(temp_str,"DLCI %d: status %s %s",
+		    snprintf(temp_str,sizeof(temp_str), "DLCI %d: status %s %s",
 			    ((ptemp[2]&0x3f)<<4)+ ((ptemp[3]&0x78)>>3), 
 			    ptemp[4] & 0x8 ?"new,":" ",
 			    ptemp[4] & 0x2 ?"Active":"Inactive");
diff --git a/contrib/tcpdump/print-icmp.c b/contrib/tcpdump/print-icmp.c
index ca2bf07afb26..a4b3dd6206df 100644
--- a/contrib/tcpdump/print-icmp.c
+++ b/contrib/tcpdump/print-icmp.c
@@ -177,7 +177,7 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 	register const struct ip *oip;
 	register const struct udphdr *ouh;
 	register u_int hlen, dport, mtu;
-	char buf[256];
+	char buf[MAXHOSTNAMELEN + 100];
 
 	dp = (struct icmp *)bp;
 	ip = (struct ip *)bp2;
@@ -198,7 +198,7 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 
 		case ICMP_UNREACH_PROTOCOL:
 			TCHECK(dp->icmp_ip.ip_p);
-			(void)sprintf(buf, "%s protocol %d unreachable",
+			(void)snprintf(buf, sizeof(buf), "%s protocol %d unreachable",
 				       ipaddr_string(&dp->icmp_ip.ip_dst),
 				       dp->icmp_ip.ip_p);
 			break;
@@ -212,21 +212,21 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 			switch (oip->ip_p) {
 
 			case IPPROTO_TCP:
-				(void)sprintf(buf,
+				(void)snprintf(buf, sizeof(buf),
 					"%s tcp port %s unreachable",
 					ipaddr_string(&oip->ip_dst),
 					tcpport_string(dport));
 				break;
 
 			case IPPROTO_UDP:
-				(void)sprintf(buf,
+				(void)snprintf(buf, sizeof(buf),
 					"%s udp port %s unreachable",
 					ipaddr_string(&oip->ip_dst),
 					udpport_string(dport));
 				break;
 
 			default:
-				(void)sprintf(buf,
+				(void)snprintf(buf, sizeof(buf),
 					"%s protocol %d port %d unreachable",
 					ipaddr_string(&oip->ip_dst),
 					oip->ip_p, dport);
@@ -241,11 +241,11 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 			mp = (struct mtu_discovery *)&dp->icmp_void;
                         mtu = EXTRACT_16BITS(&mp->nexthopmtu);
                         if (mtu)
-			    (void)sprintf(buf,
+			    (void)snprintf(buf, sizeof(buf),
 				"%s unreachable - need to frag (mtu %d)",
 				ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
                         else
-			    (void)sprintf(buf,
+			    (void)snprintf(buf, sizeof(buf),
 				"%s unreachable - need to frag",
 				ipaddr_string(&dp->icmp_ip.ip_dst));
 			}
@@ -254,7 +254,7 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 		default:
 			fmt = tok2str(unreach2str, "#%d %%s unreachable",
 			    dp->icmp_code);
-			(void)sprintf(buf, fmt,
+			(void)snprintf(buf, sizeof(buf), fmt,
 			    ipaddr_string(&dp->icmp_ip.ip_dst));
 			break;
 		}
@@ -264,7 +264,7 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 		TCHECK(dp->icmp_ip.ip_dst);
 		fmt = tok2str(type2str, "redirect-#%d %%s to net %%s",
 		    dp->icmp_code);
-		(void)sprintf(buf, fmt,
+		(void)snprintf(buf, sizeof(buf), fmt,
 		    ipaddr_string(&dp->icmp_ip.ip_dst),
 		    ipaddr_string(&dp->icmp_gwaddr));
 		break;
@@ -284,30 +284,30 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 		cp = buf + strlen(buf);
 		lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
 		if (lifetime < 60)
-			(void)sprintf(cp, "%u", lifetime);
+			(void)snprintf(cp, sizeof(buf) - strlen(buf), "%u", lifetime);
 		else if (lifetime < 60 * 60)
-			(void)sprintf(cp, "%u:%02u",
+			(void)snprintf(cp, sizeof(buf) - strlen(buf), "%u:%02u",
 			    lifetime / 60, lifetime % 60);
 		else
-			(void)sprintf(cp, "%u:%02u:%02u",
+			(void)snprintf(cp, sizeof(buf) - strlen(buf), "%u:%02u:%02u",
 			    lifetime / 3600,
 			    (lifetime % 3600) / 60,
 			    lifetime % 60);
 		cp = buf + strlen(buf);
 
 		num = ihp->ird_addrnum;
-		(void)sprintf(cp, " %d:", num);
+		(void)snprintf(cp, sizeof(buf) - strlen(buf), " %d:", num);
 		cp = buf + strlen(buf);
 
 		size = ihp->ird_addrsiz;
 		if (size != 2) {
-			(void)sprintf(cp, " [size %d]", size);
+			(void)snprintf(cp, sizeof(buf) - strlen(buf), " [size %d]", size);
 			break;
 		}
 		idp = (struct id_rdiscovery *)&dp->icmp_data;
 		while (num-- > 0) {
 			TCHECK(*idp);
-			(void)sprintf(cp, " {%s %u}",
+			(void)snprintf(cp, sizeof(buf) - strlen(buf), " {%s %u}",
 			    ipaddr_string(&idp->ird_addr),
 			    EXTRACT_32BITS(&idp->ird_pref));
 			cp = buf + strlen(buf);
@@ -328,25 +328,25 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
 			break;
 
 		default:
-			(void)sprintf(buf, "time exceeded-#%d", dp->icmp_code);
+			(void)snprintf(buf, sizeof(buf), "time exceeded-#%d", dp->icmp_code);
 			break;
 		}
 		break;
 
 	case ICMP_PARAMPROB:
 		if (dp->icmp_code)
-			(void)sprintf(buf, "parameter problem - code %d",
+			(void)snprintf(buf, sizeof(buf), "parameter problem - code %d",
 					dp->icmp_code);
 		else {
 			TCHECK(dp->icmp_pptr);
-			(void)sprintf(buf, "parameter problem - octet %d",
+			(void)snprintf(buf, sizeof(buf), "parameter problem - octet %d",
 					dp->icmp_pptr);
 		}
 		break;
 
 	case ICMP_MASKREPLY:
 		TCHECK(dp->icmp_mask);
-		(void)sprintf(buf, "address mask is 0x%08x",
+		(void)snprintf(buf, sizeof(buf), "address mask is 0x%08x",
 		    (u_int32_t)ntohl(dp->icmp_mask));
 		break;
 
diff --git a/contrib/tcpdump/print-sunrpc.c b/contrib/tcpdump/print-sunrpc.c
index 54dcf66a2f49..ddac9138321e 100644
--- a/contrib/tcpdump/print-sunrpc.c
+++ b/contrib/tcpdump/print-sunrpc.c
@@ -132,7 +132,9 @@ progstr(prog)
 	rp = getrpcbynumber(prog);
 	if (rp == NULL)
 		(void) sprintf(buf, "#%u", prog);
-	else
-		strcpy(buf, rp->r_name);
+	else {
+		strncpy(buf, rp->r_name, sizeof(buf)-1);
+		buf[sizeof(buf)-1] = '\0';
+	}
 	return (buf);
 }