Author: delphij
Date: Thu Jan  5 09:23:54 2017
New Revision: 311392
URL: https://svnweb.freebsd.org/changeset/base/311392

Log:
  Use strlcpy and snprintf in netstat(1).
  
  Expand inet6name() line buffer to NI_MAXHOST and use strlcpy/snprintf
  in various places.
  
  Reported by:  Anton Yuzhaninov <citrin citrin ru>
  MFC after:    3 days
  Differential Revision:        https://reviews.freebsd.org/D8916

Modified:
  head/usr.bin/netstat/if.c
  head/usr.bin/netstat/inet.c
  head/usr.bin/netstat/inet6.c
  head/usr.bin/netstat/mroute.c
  head/usr.bin/netstat/netstat.h
  head/usr.bin/netstat/route.c
  head/usr.bin/netstat/sctp.c
  head/usr.bin/netstat/unix.c

Modified: head/usr.bin/netstat/if.c
==============================================================================
--- head/usr.bin/netstat/if.c   Thu Jan  5 08:57:49 2017        (r311391)
+++ head/usr.bin/netstat/if.c   Thu Jan  5 09:23:54 2017        (r311392)
@@ -393,10 +393,10 @@ intpr(void (*pfunc)(char *), int af)
                case AF_LINK:
                    {
                        struct sockaddr_dl *sdl;
-                       char linknum[10];
+                       char linknum[sizeof("<Link#32767>")];
 
                        sdl = (struct sockaddr_dl *)ifa->ifa_addr;
-                       sprintf(linknum, "<Link#%d>", sdl->sdl_index);
+                       snprintf(linknum, sizeof(linknum), "<Link#%d>", 
sdl->sdl_index);
                        xo_emit("{t:network/%-*.*s} ", net_len, net_len,
                            linknum);
                        if (sdl->sdl_nlen == 0 &&

Modified: head/usr.bin/netstat/inet.c
==============================================================================
--- head/usr.bin/netstat/inet.c Thu Jan  5 08:57:49 2017        (r311391)
+++ head/usr.bin/netstat/inet.c Thu Jan  5 09:23:54 2017        (r311392)
@@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$");
 #include "netstat.h"
 #include "nl_defs.h"
 
-char   *inetname(struct in_addr *);
 void   inetprint(const char *, struct in_addr *, int, const char *, int,
     const int);
 #ifdef INET6
@@ -1413,21 +1412,26 @@ inetprint(const char *container, struct 
        struct servent *sp = 0;
        char line[80], *cp;
        int width;
+       size_t alen, plen;
 
        if (container)
                xo_open_container(container);
 
        if (Wflag)
-           sprintf(line, "%s.", inetname(in));
+           snprintf(line, sizeof(line), "%s.", inetname(in));
        else
-           sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, 
inetname(in));
-       cp = strchr(line, '\0');
+           snprintf(line, sizeof(line), "%.*s.",
+               (Aflag && !num_port) ? 12 : 16, inetname(in));
+       alen = strlen(line);
+       cp = line + alen;
        if (!num_port && port)
                sp = getservbyport((int)port, proto);
        if (sp || port == 0)
-               sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
+               snprintf(cp, sizeof(line) - alen,
+                   "%.15s ", sp ? sp->s_name : "*");
        else
-               sprintf(cp, "%d ", ntohs((u_short)port));
+               snprintf(cp, sizeof(line) - alen,
+                   "%d ", ntohs((u_short)port));
        width = (Aflag && !Wflag) ? 18 :
                ((!Wflag || af1 == AF_INET) ? 22 : 45);
        if (Wflag)
@@ -1435,7 +1439,8 @@ inetprint(const char *container, struct 
        else
                xo_emit("{d:target/%-*.*s} ", width, width, line);
 
-       int alen = cp - line - 1, plen = strlen(cp) - 1;
+       plen = strlen(cp) - 1;
+       alen--;
        xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
            plen, cp);
 
@@ -1481,8 +1486,9 @@ inetname(struct in_addr *inp)
        } else {
                inp->s_addr = ntohl(inp->s_addr);
 #define        C(x)    ((u_int)((x) & 0xff))
-               sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
-                   C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
+               snprintf(line, sizeof(line), "%u.%u.%u.%u",
+                   C(inp->s_addr >> 24), C(inp->s_addr >> 16),
+                   C(inp->s_addr >> 8), C(inp->s_addr));
        }
        return (line);
 }

Modified: head/usr.bin/netstat/inet6.c
==============================================================================
--- head/usr.bin/netstat/inet6.c        Thu Jan  5 08:57:49 2017        
(r311391)
+++ head/usr.bin/netstat/inet6.c        Thu Jan  5 09:23:54 2017        
(r311392)
@@ -70,8 +70,6 @@ __FBSDID("$FreeBSD$");
 #include <libxo/xo.h>
 #include "netstat.h"
 
-char   *inet6name(struct in6_addr *);
-
 static char ntop_buf[INET6_ADDRSTRLEN];
 
 static const char *ip6nh[] = {
@@ -1270,24 +1268,30 @@ inet6print(const char *container, struct
        struct servent *sp = 0;
        char line[80], *cp;
        int width;
+       size_t alen, plen;
 
        if (container)
                xo_open_container(container);
 
-       sprintf(line, "%.*s.", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
+       snprintf(line, sizeof(line), "%.*s.",
+           Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
            inet6name(in6));
-       cp = strchr(line, '\0');
+       alen = strlen(line);
+       cp = line + alen;
        if (!numeric && port)
                GETSERVBYPORT6(port, proto, sp);
        if (sp || port == 0)
-               sprintf(cp, "%.15s", sp ? sp->s_name : "*");
+               snprintf(cp, sizeof(line) - alen,
+                   "%.15s", sp ? sp->s_name : "*");
        else
-               sprintf(cp, "%d", ntohs((u_short)port));
+               snprintf(cp, sizeof(line) - alen,
+                   "%d", ntohs((u_short)port));
        width = Wflag ? 45 : Aflag ? 18 : 22;
 
        xo_emit("{d:target/%-*.*s} ", width, width, line);
 
-       int alen = cp - line - 1, plen = strlen(cp) - 1;
+       plen = strlen(cp) - 1;
+       alen--;
        xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
            plen, cp);
 
@@ -1306,7 +1310,7 @@ inet6name(struct in6_addr *in6p)
 {
        struct sockaddr_in6 sin6;
        char hbuf[NI_MAXHOST], *cp;
-       static char line[50];
+       static char line[NI_MAXHOST];
        static char domain[MAXHOSTNAMELEN];
        static int first = 1;
        int flags, error;
@@ -1317,9 +1321,9 @@ inet6name(struct in6_addr *in6p)
        }
        if (first && !numeric_addr) {
                first = 0;
-               if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
+               if (gethostname(domain, sizeof(domain)) == 0 &&
                    (cp = strchr(domain, '.')))
-                       (void) strcpy(domain, cp + 1);
+                       strlcpy(domain, cp + 1, sizeof(domain));
                else
                        domain[0] = 0;
        }
@@ -1336,10 +1340,10 @@ inet6name(struct in6_addr *in6p)
                    (cp = strchr(hbuf, '.')) &&
                    !strcmp(cp + 1, domain))
                        *cp = 0;
-               strcpy(line, hbuf);
+               strlcpy(line, hbuf, sizeof(line));
        } else {
                /* XXX: this should not happen. */
-               sprintf(line, "%s",
+               snprintf(line, sizeof(line), "%s",
                        inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
                                sizeof(ntop_buf)));
        }

Modified: head/usr.bin/netstat/mroute.c
==============================================================================
--- head/usr.bin/netstat/mroute.c       Thu Jan  5 08:57:49 2017        
(r311391)
+++ head/usr.bin/netstat/mroute.c       Thu Jan  5 09:23:54 2017        
(r311392)
@@ -100,17 +100,19 @@ print_bw_meter(struct bw_meter *bw_meter
 
        /* The measured values */
        if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) {
-               sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_measured.b_packets);
+               snprintf(s1, sizeof(s1), "%ju",
+                   (uintmax_t)bw_meter->bm_measured.b_packets);
                xo_emit("{e:measured-packets/%ju}",
                    (uintmax_t)bw_meter->bm_measured.b_packets);
        } else
-               sprintf(s1, "?");
+               strcpy(s1, "?");
        if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) {
-               sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_measured.b_bytes);
+               snprintf(s2, sizeof(s2), "%ju",
+                   (uintmax_t)bw_meter->bm_measured.b_bytes);
                xo_emit("{e:measured-bytes/%ju}",
                    (uintmax_t)bw_meter->bm_measured.b_bytes);
        } else
-               sprintf(s2, "?");
+               strcpy(s2, "?");
        xo_emit("  {[:-30}{:start-time/%lu.%06lu}|{q:measured-packets/%s}"
            "|{q:measured-bytes%s}{]:}",
            (u_long)bw_meter->bm_start_time.tv_sec,
@@ -122,17 +124,19 @@ print_bw_meter(struct bw_meter *bw_meter
 
        /* The threshold values */
        if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) {
-               sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_threshold.b_packets);
+               snprintf(s1, sizeof(s1), "%ju",
+                   (uintmax_t)bw_meter->bm_threshold.b_packets);
                xo_emit("{e:threshold-packets/%ju}",
                    (uintmax_t)bw_meter->bm_threshold.b_packets);
        } else
-               sprintf(s1, "?");
+               strcpy(s1, "?");
        if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) {
-               sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_threshold.b_bytes);
+               snprintf(s2, sizeof(s2), "%ju",
+                   (uintmax_t)bw_meter->bm_threshold.b_bytes);
                xo_emit("{e:threshold-bytes/%ju}",
                    (uintmax_t)bw_meter->bm_threshold.b_bytes);
        } else
-               sprintf(s2, "?");
+               strcpy(s2, "?");
 
        xo_emit("  {[:-30}{:threshold-time/%lu.%06lu}|{q:threshold-packets/%s}"
            "|{q:threshold-bytes%s}{]:}",
@@ -144,13 +148,13 @@ print_bw_meter(struct bw_meter *bw_meter
                 &bw_meter->bm_threshold.b_time, &end);
        if (timercmp(&now, &end, <=)) {
                timersub(&end, &now, &delta);
-               sprintf(s3, "%lu.%06lu",
+               snprintf(s3, sizeof(s3), "%lu.%06lu",
                        (u_long)delta.tv_sec,
                        (u_long)delta.tv_usec);
        } else {
                /* Negative time */
                timersub(&now, &end, &delta);
-               sprintf(s3, "-%lu.06%lu",
+               snprintf(s3, sizeof(s3), "-%lu.06%lu",
                        (u_long)delta.tv_sec,
                        (u_long)delta.tv_usec);
        }

Modified: head/usr.bin/netstat/netstat.h
==============================================================================
--- head/usr.bin/netstat/netstat.h      Thu Jan  5 08:57:49 2017        
(r311391)
+++ head/usr.bin/netstat/netstat.h      Thu Jan  5 09:23:54 2017        
(r311392)
@@ -100,7 +100,16 @@ void       ah_stats(u_long, const char *, int,
 void   ipcomp_stats(u_long, const char *, int, int);
 #endif
 
+#ifdef INET
+struct in_addr;
+
+char   *inetname(struct in_addr *);
+#endif
+
 #ifdef INET6
+struct in6_addr;
+
+char   *inet6name(struct in6_addr *);
 void   ip6_stats(u_long, const char *, int, int);
 void   ip6_ifstats(char *);
 void   icmp6_stats(u_long, const char *, int, int);

Modified: head/usr.bin/netstat/route.c
==============================================================================
--- head/usr.bin/netstat/route.c        Thu Jan  5 08:57:49 2017        
(r311391)
+++ head/usr.bin/netstat/route.c        Thu Jan  5 09:23:54 2017        
(r311392)
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
 #include <ifaddrs.h>
 #include <libutil.h>
 #include <netdb.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -115,7 +116,7 @@ static const char *fmt_sockaddr(struct s
     int flags);
 static void p_flags(int, const char *);
 static const char *fmt_flags(int f);
-static void domask(char *, in_addr_t, u_long);
+static void domask(char *, size_t, u_long);
 
 
 /*
@@ -494,12 +495,16 @@ fmt_sockaddr(struct sockaddr *sa, struct
 
                cq = buf;
                slim =  sa->sa_len + (u_char *) sa;
-               cqlim = cq + sizeof(buf) - 6;
-               cq += sprintf(cq, "(%d)", sa->sa_family);
+               cqlim = cq + sizeof(buf) - sizeof(" ffff");
+               snprintf(cq, sizeof(cq), "(%d)", sa->sa_family);
+               cq += strlen(cq);
                while (s < slim && cq < cqlim) {
-                       cq += sprintf(cq, " %02x", *s++);
-                       if (s < slim)
-                           cq += sprintf(cq, "%02x", *s++);
+                       snprintf(cq, sizeof(" ff"), " %02x", *s++);
+                       cq += strlen(cq);
+                       if (s < slim) {
+                           snprintf(cq, sizeof("ff"), "%02x", *s++);
+                           cq += strlen(cq);
+                       }
                }
                cp = buf;
            }
@@ -576,7 +581,7 @@ routename(struct sockaddr *sa, int flags
        0)
 
 static void
-domask(char *dst, in_addr_t addr __unused, u_long mask)
+domask(char *dst, size_t buflen, u_long mask)
 {
        int b, i;
 
@@ -598,9 +603,9 @@ domask(char *dst, in_addr_t addr __unuse
                        break;
                }
        if (i == -1)
-               sprintf(dst, "&0x%lx", mask);
+               snprintf(dst, buflen, "&0x%lx", mask);
        else
-               sprintf(dst, "/%d", 32-i);
+               snprintf(dst, buflen, "/%d", 32-i);
 }
 
 /*
@@ -631,7 +636,7 @@ static const char *
 netname4(in_addr_t in, in_addr_t mask)
 {
        char *cp = 0;
-       static char line[MAXHOSTNAMELEN + sizeof("/xx")];
+       static char line[MAXHOSTNAMELEN + sizeof("&0xffffffff")];
        char nline[INET_ADDRSTRLEN];
        struct netent *np = 0;
        in_addr_t i;
@@ -657,7 +662,7 @@ netname4(in_addr_t in, in_addr_t mask)
        else {
                inet_ntop(AF_INET, &in, nline, sizeof(nline));
                strlcpy(line, nline, sizeof(line));
-               domask(line + strlen(line), i, ntohl(mask));
+               domask(line + strlen(line), sizeof(line) - strlen(line), 
ntohl(mask));
        }
 
        return (line);
@@ -686,7 +691,7 @@ in6_fillscopeid(struct sockaddr_in6 *sa6
 }
 
 /* Mask to length table.  To check an invalid value, (length + 1) is used. */
-static int masktolen[256] = {
+static const u_char masktolen[256] = {
        [0xff] = 8 + 1,
        [0xfe] = 7 + 1,
        [0xfc] = 6 + 1,
@@ -704,17 +709,20 @@ netname6(struct sockaddr_in6 *sa6, struc
        static char line[NI_MAXHOST + sizeof("/xxx") - 1];
        struct sockaddr_in6 addr;
        char nline[NI_MAXHOST];
+       char maskbuf[sizeof("/xxx")];
        u_char *p, *lim;
-       int masklen, illegal = 0, i;
+       u_char masklen;
+       int i;
+       bool illegal = false;
 
        if (mask) {
                p = (u_char *)&mask->sin6_addr;
                for (masklen = 0, lim = p + 16; p < lim; p++) {
-                       if (masktolen[*p] > 0)
+                       if (masktolen[*p] > 0) {
                                /* -1 is required. */
-                               masklen += masktolen[*p] - 1;
-                       else
-                               illegal++;
+                               masklen += (masktolen[*p] - 1);
+                       } else
+                               illegal = true;
                }
                if (illegal)
                        xo_error("illegal prefixlen\n");
@@ -738,8 +746,10 @@ netname6(struct sockaddr_in6 *sa6, struc
        else
                getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, line,
                    sizeof(line), NULL, 0, 0);
-       if (numeric_addr || strcmp(line, nline) == 0)
-               sprintf(&line[strlen(line)], "/%d", masklen);
+       if (numeric_addr || strcmp(line, nline) == 0) {
+               snprintf(maskbuf, sizeof(maskbuf), "/%d", masklen);
+               strlcat(line, maskbuf, sizeof(line));
+       }
 
        return (line);
 }

Modified: head/usr.bin/netstat/sctp.c
==============================================================================
--- head/usr.bin/netstat/sctp.c Thu Jan  5 08:57:49 2017        (r311391)
+++ head/usr.bin/netstat/sctp.c Thu Jan  5 09:23:54 2017        (r311392)
@@ -104,16 +104,6 @@ struct xraddr_entry {
        LIST_ENTRY(xraddr_entry) xraddr_entries;
 };
 
-#ifdef INET
-char *
-inetname(struct in_addr *inp);
-#endif
-
-#ifdef INET6
-char *
-inet6name(struct in6_addr *in6p);
-#endif
-
 static void
 sctp_print_address(const char *container, union sctp_sockstore *address,
     int port, int num_port)
@@ -121,6 +111,7 @@ sctp_print_address(const char *container
        struct servent *sp = 0;
        char line[80], *cp;
        int width;
+       size_t alen, plen;
 
        if (container)
                xo_open_container(container);
@@ -128,29 +119,36 @@ sctp_print_address(const char *container
        switch (address->sa.sa_family) {
 #ifdef INET
        case AF_INET:
-               sprintf(line, "%.*s.", Wflag ? 39 : 16, 
inetname(&address->sin.sin_addr));
+               snprintf(line, sizeof(line), "%.*s.",
+                   Wflag ? 39 : 16, inetname(&address->sin.sin_addr));
                break;
 #endif
 #ifdef INET6
        case AF_INET6:
-               sprintf(line, "%.*s.", Wflag ? 39 : 16, 
inet6name(&address->sin6.sin6_addr));
+               snprintf(line, sizeof(line), "%.*s.",
+                   Wflag ? 39 : 16, inet6name(&address->sin6.sin6_addr));
                break;
 #endif
        default:
-               sprintf(line, "%.*s.", Wflag ? 39 : 16, "");
+               snprintf(line, sizeof(line), "%.*s.",
+                   Wflag ? 39 : 16, "");
                break;
        }
-       cp = strchr(line, '\0');
+       alen = strlen(line);
+       cp = line + alen;
        if (!num_port && port)
                sp = getservbyport((int)port, "sctp");
        if (sp || port == 0)
-               sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
+               snprintf(cp, sizeof(line) - alen,
+                   "%.15s ", sp ? sp->s_name : "*");
        else
-               sprintf(cp, "%d ", ntohs((u_short)port));
+               snprintf(cp, sizeof(line) - alen,
+                   "%d ", ntohs((u_short)port));
        width = Wflag ? 45 : 22;
        xo_emit("{d:target/%-*.*s} ", width, width, line);
 
-       int alen = cp - line - 1, plen = strlen(cp) - 1;
+       plen = strlen(cp) - 1;
+       alen--;
        xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
            plen, cp);
 

Modified: head/usr.bin/netstat/unix.c
==============================================================================
--- head/usr.bin/netstat/unix.c Thu Jan  5 08:57:49 2017        (r311391)
+++ head/usr.bin/netstat/unix.c Thu Jan  5 09:23:54 2017        (r311392)
@@ -75,7 +75,7 @@ pcblist_sysctl(int type, char **bufp)
        size_t  len;
        char mibvar[sizeof "net.local.seqpacket.pcblist"];
 
-       sprintf(mibvar, "net.local.%s.pcblist", socktype[type]);
+       snprintf(mibvar, sizeof(mibvar), "net.local.%s.pcblist", 
socktype[type]);
 
        len = 0;
        if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to