Date: Mon, 20 Oct 2014 16:29:07 +0900 (JST) From: Hiroki Sato <hrs@FreeBSD.org> To: brde@optusnet.com.au Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r273295 - in head/sbin: ping ping6 Message-ID: <20141020.162907.106891462107570268.hrs@allbsd.org> In-Reply-To: <20141020140848.D935@besplex.bde.org> References: <201410200027.s9K0RegN062458@svn.freebsd.org> <20141020140848.D935@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
----Security_Multipart0(Mon_Oct_20_16_29_08_2014_920)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Mon_Oct_20_16_29_07_2014_483)--" Content-Transfer-Encoding: 7bit ----Next_Part(Mon_Oct_20_16_29_07_2014_483)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi Bruce, Thank you for your review. I fixed lines you pointed out and attached a patch candidate. I will show each change line by line in this email, too: Bruce Evans <brde@optusnet.com.au> wrote in <20141020140848.D935@besplex.bde.org>: br> > - if (cc - ICMP_MINLEN - phdr_len >= sizeof(tv1)) { br> > + if ((size_t)(cc - ICMP_MINLEN - phdr_len) >= br> > + sizeof(tv1)) { br> > /* Copy to avoid alignment problems: */ br> > memcpy(&tv32, tp, sizeof(tv32)); br> > tv1.tv_sec = ntohl(tv32.tv32_sec); br> br> This breaks the warning, and breaks the code on exotic (unsupported) br> where it used to work accidentally. The code was already broken on br> non-exotic arches. - if ((size_t)(cc - ICMP_MINLEN - phdr_len) >= - sizeof(tv1)) { + if (cc - ICMP_MINLEN - phdr_len >= (int)sizeof(tv1)) { br> > -struct sockaddr_in6 dst; /* who to ping6 */ br> > -struct sockaddr_in6 src; /* src addr of this packet */ br> > -socklen_t srclen; br> br> Old code like ping uses plain int for almost everything except where br> the broken ABI requires an unsigned type like socklen_t. -static socklen_t srclen; -static size_t datalen = DEFDATALEN; +static int srclen; +static int datalen = DEFDATALEN; br> > +static u_int8_t nonce[8]; /* nonce field for node information */ br> br> This uses the deprecated nonstandard spelling of uint8_t. s/u_int_{8,16,32}_t/uint_{8,16,32}_t/ in various places. br> > -void pr_suptypes(struct icmp6_nodeinfo *, size_t); s/size_t/int/ br> > - sockbufsize = lsockbufsize; br> > + sockbufsize = (int)lsockbufsize; br> > if (errno || !*optarg || *e || br> > - sockbufsize != lsockbufsize) br> > + lsockbufsize > INT_MAX) br> > errx(1, "invalid socket buffer size"); br> I don't like warnings about hackish but correct code like the previous br> version of the above. Does the compiler actually complain about br> comparing br> ints with unsigned longs for equality? Yes, this part caused the following warning: /usr/src/head/sbin/ping6/ping6.c:395:20: error: comparison of integers of different signs: 'int' and 'u_long' (aka 'unsigned long') [-Werror,-Wsign-compare] sockbufsize != lsockbufsize) br> If you are going to change the range check, then rearrange the code. br> It br> was arranged to set sockbufsize before the value is known to fit so br> that br> non-fitting values can be checked. With range checking on the br> br> original br> value, it is more natural to not do the assignment until after the br> check has passed. Then the cast should be unnecessary since a smart br> compiler would see from the range check that the assignment can't br> overflow. - lsockbufsize = strtoul(optarg, &e, 10); - sockbufsize = (int)lsockbufsize; - if (errno || !*optarg || *e || - lsockbufsize > INT_MAX) + ultmp = strtoul(optarg, &e, 10); + if (errno || !*optarg || *e || ultmp > INT_MAX) errx(1, "invalid socket buffer size"); + sockbufsize = ultmp; br> > - if (l >= sizeof(cresult) || l < 0) br> > + if ((size_t)l >= sizeof(cresult) || l < 0) br> br> The conversion is backwards. br> - if ((size_t)l >= sizeof(cresult) || l < 0) + if (l >= (int)sizeof(cresult) || l < 0) br> > - if (end - (u_char *)ip6 < sizeof(*ip6)) { br> > + if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) { br> > printf("IP6"); br> > goto trunc; br> > } br> br> Backwards. The RHS should be cast to ptrdiff_t. Pointer difference br> are only required to work up to 64K, but that is enough for the size br> of small objects. - if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) { + if (end - (u_char *)ip6 < (ptrdiff_t)sizeof(*ip6)) { br> > - kk <= MAXDATALEN - (8 + sizeof(struct tv32) + ii); br> > + (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii; - (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii; + kk <= MAXDATALEN - 8 + (int)sizeof(struct tv32) + ii; -- Hiroki ----Next_Part(Mon_Oct_20_16_29_07_2014_483)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ping6.c_20141020-1.diff" Index: ping6.c =================================================================== --- ping6.c (revision 273295) +++ ping6.c (working copy) @@ -122,6 +122,7 @@ #include <fcntl.h> #include <math.h> #include <signal.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -136,8 +137,8 @@ #include <md5.h> struct tv32 { - u_int32_t tv32_sec; - u_int32_t tv32_usec; + uint32_t tv32_sec; + uint32_t tv32_usec; }; #define MAXPACKETLEN 131072 @@ -210,8 +211,8 @@ static struct sockaddr_in6 dst; /* who to ping6 */ static struct sockaddr_in6 src; /* src addr of this packet */ -static socklen_t srclen; -static size_t datalen = DEFDATALEN; +static int srclen; +static int datalen = DEFDATALEN; static int s; /* socket file descriptor */ static u_char outpack[MAXPACKETLEN]; static char BSPACE = '\b'; /* characters written for flood */ @@ -219,7 +220,7 @@ static char DOT = '.'; static char *hostname; static int ident; /* process id to identify our packets */ -static u_int8_t nonce[8]; /* nonce field for node information */ +static u_char nonce[8]; /* nonce field for node information */ static int hoplimit = -1; /* hoplimit */ static u_char *packet = NULL; @@ -265,17 +266,17 @@ static const char *pr_addr(struct sockaddr *, int); static void pr_icmph(struct icmp6_hdr *, u_char *); static void pr_iph(struct ip6_hdr *); -static void pr_suptypes(struct icmp6_nodeinfo *, size_t); +static void pr_suptypes(struct icmp6_nodeinfo *, int); static void pr_nodeaddr(struct icmp6_nodeinfo *, int); static int myechoreply(const struct icmp6_hdr *); static int mynireply(const struct icmp6_nodeinfo *); static char *dnsdecode(const u_char **, const u_char *, const u_char *, - char *, size_t); + char *, int); static void pr_pack(u_char *, int, struct msghdr *); static void pr_exthdrs(struct msghdr *); -static void pr_ip6opt(void *, size_t); -static void pr_rthdr(void *, size_t); -static int pr_bitrange(u_int32_t, int, int); +static void pr_ip6opt(void *, int); +static void pr_rthdr(void *, int); +static int pr_bitrange(uint32_t, int, int); static void pr_retip(struct ip6_hdr *, u_char *); static void summary(void); static void tvsub(struct timeval *, struct timeval *); @@ -303,7 +304,6 @@ /* For control (ancillary) data received from recvmsg() */ struct cmsghdr cm[CONTROLLEN]; #if defined(SO_SNDBUF) && defined(SO_RCVBUF) - u_long lsockbufsize; int sockbufsize = 0; #endif int usepktinfo = 0; @@ -316,7 +316,7 @@ char *policy_out = NULL; #endif double t; - u_long alarmtimeout; + u_long alarmtimeout, ultmp; size_t rthlen; #ifdef IPV6_USE_MIN_MTU int mflag = 0; @@ -388,11 +388,10 @@ #if defined(SO_SNDBUF) && defined(SO_RCVBUF) errno = 0; e = NULL; - lsockbufsize = strtoul(optarg, &e, 10); - sockbufsize = (int)lsockbufsize; - if (errno || !*optarg || *e || - lsockbufsize > INT_MAX) + ultmp = strtoul(optarg, &e, 10); + if (errno || !*optarg || *e || ultmp > INT_MAX) errx(1, "invalid socket buffer size"); + sockbufsize = ultmp; #else errx(1, "-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported"); @@ -522,14 +521,15 @@ options |= F_SRCADDR; break; case 's': /* size of packet to send */ - datalen = strtol(optarg, &e, 10); - if (datalen <= 0 || *optarg == '\0' || *e != '\0') - errx(1, "illegal datalen value -- %s", optarg); - if (datalen > MAXDATALEN) { - errx(1, - "datalen value too large, maximum is %d", + ultmp = strtoul(optarg, &e, 10); + if (*e || e == optarg) + errx(EX_USAGE, "invalid packet size: `%s'", + optarg); + if (ultmp > MAXDATALEN) + errx(EX_USAGE, + "packetsize too large, maximum is %d", MAXDATALEN); - } + datalen = ultmp; break; case 't': options &= ~F_NOUSERDATA; @@ -718,7 +718,7 @@ errx(1, "-f and -i incompatible options"); if ((options & F_NOUSERDATA) == 0) { - if (datalen >= sizeof(struct tv32)) { + if (datalen >= (int)sizeof(struct tv32)) { /* we can time transfer */ timing = 1; } else @@ -746,12 +746,12 @@ gettimeofday(&seed, NULL); srand((unsigned int)(seed.tv_sec ^ seed.tv_usec ^ (long)ident)); memset(nonce, 0, sizeof(nonce)); - for (i = 0; i < sizeof(nonce); i += sizeof(int)) + for (i = 0; i < (int)sizeof(nonce); i += sizeof(int)) *((int *)&nonce[i]) = rand(); #else memset(nonce, 0, sizeof(nonce)); - for (i = 0; i < (int)sizeof(nonce); i += sizeof(u_int32_t)) - *((u_int32_t *)&nonce[i]) = arc4random(); + for (i = 0; i < (int)sizeof(nonce); i += sizeof(uint32_t)) + *((uint32_t *)&nonce[i]) = arc4random(); #endif optval = 1; if (options & F_DONTFRAG) @@ -1008,7 +1008,7 @@ #if defined(SO_SNDBUF) && defined(SO_RCVBUF) if (sockbufsize) { - if (datalen > (size_t)sockbufsize) + if (datalen > sockbufsize) warnx("you need -b to increase socket buffer size"); if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof(sockbufsize)) < 0) @@ -1292,7 +1292,7 @@ memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); + *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq); memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, sizeof(dst.sin6_addr)); @@ -1307,7 +1307,7 @@ memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); + *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq); cc = ICMP6_NIQLEN; datalen = 0; @@ -1319,7 +1319,7 @@ memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); + *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq); memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, sizeof(dst.sin6_addr)); @@ -1334,7 +1334,7 @@ memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); + *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq); cc = ICMP6_NIQLEN; datalen = 0; } else { @@ -1392,9 +1392,9 @@ static int mynireply(const struct icmp6_nodeinfo *nip) { - if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t), - nonce + sizeof(u_int16_t), - sizeof(nonce) - sizeof(u_int16_t)) == 0) + if (memcmp(nip->icmp6_ni_nonce + sizeof(uint16_t), + nonce + sizeof(uint16_t), + sizeof(nonce) - sizeof(uint16_t)) == 0) return 1; else return 0; @@ -1402,7 +1402,7 @@ static char * dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf, - size_t bufsiz) + int bufsiz) /*base for compressed name*/ { int i; @@ -1419,7 +1419,7 @@ while (cp < ep) { i = *cp; if (i == 0 || cp != *sp) { - if (strlcat((char *)buf, ".", bufsiz) >= bufsiz) + if ((int)strlcat((char *)buf, ".", bufsiz) >= bufsiz) return NULL; /*result overrun*/ } if (i == 0) @@ -1435,7 +1435,7 @@ if (dnsdecode(&comp, cp, base, cresult, sizeof(cresult)) == NULL) return NULL; - if (strlcat(buf, cresult, bufsiz) >= bufsiz) + if ((int)strlcat(buf, cresult, bufsiz) >= bufsiz) return NULL; /*result overrun*/ break; } else if ((i & 0x3f) == i) { @@ -1444,9 +1444,10 @@ while (i-- > 0 && cp < ep) { l = snprintf(cresult, sizeof(cresult), isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff); - if ((size_t)l >= sizeof(cresult) || l < 0) + if (l >= (int)sizeof(cresult) || l < 0) return NULL; - if (strlcat(buf, cresult, bufsiz) >= bufsiz) + if ((int)strlcat(buf, cresult, bufsiz) >= + bufsiz) return NULL; /*result overrun*/ cp++; } @@ -1485,7 +1486,7 @@ int dupflag; size_t off; int oldfqdn; - u_int16_t seq; + uint16_t seq; char dnsname[MAXDNAME + 1]; (void)gettimeofday(&tv, NULL); @@ -1591,7 +1592,7 @@ } } } else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) { - seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce); + seq = ntohs(*(uint16_t *)ni->icmp6_ni_nonce); ++nreceived; if (TST(seq % mx_dup_ck)) { ++nrepeats; @@ -1792,16 +1793,16 @@ #ifdef USE_RFC2292BIS static void -pr_ip6opt(void *extbuf, size_t bufsize) +pr_ip6opt(void *extbuf, int bufsize) { struct ip6_hbh *ext; int currentlen; - u_int8_t type; + u_char type; socklen_t extlen, len; void *databuf; size_t offset; - u_int16_t value2; - u_int32_t value4; + uint16_t value2; + uint32_t value4; ext = (struct ip6_hbh *)extbuf; extlen = (ext->ip6h_len + 1) * 8; @@ -1812,7 +1813,7 @@ * Bounds checking on the ancillary data buffer: * subtract the size of a cmsg structure from the buffer size. */ - if (bufsize < (extlen + CMSG_SPACE(0))) { + if (bufsize < (int)(extlen + CMSG_SPACE(0))) { extlen = bufsize - CMSG_SPACE(0); warnx("options truncated, showing only %u (total=%u)", (unsigned int)(extlen / 8 - 1), @@ -1835,7 +1836,7 @@ offset = inet6_opt_get_val(databuf, offset, &value4, sizeof(value4)); printf(" Jumbo Payload Opt: Length %u\n", - (u_int32_t)ntohl(value4)); + (uint32_t)ntohl(value4)); break; case IP6OPT_ROUTER_ALERT: offset = 0; @@ -1864,7 +1865,7 @@ #ifdef USE_RFC2292BIS static void -pr_rthdr(void *extbuf, size_t bufsize) +pr_rthdr(void *extbuf, int bufsize) { struct in6_addr *in6; char ntopbuf[INET6_ADDRSTRLEN]; @@ -1892,7 +1893,7 @@ * dividend is not evenly divisible by the divisor */ rthsize = (rh->ip6r_len + 1) * 8; - if (bufsize < (rthsize + CMSG_SPACE(0))) { + if (bufsize < (int)(rthsize + CMSG_SPACE(0))) { origsegs = segments; size0 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 0); size1 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 1); @@ -1929,7 +1930,7 @@ #endif /* USE_RFC2292BIS */ static int -pr_bitrange(u_int32_t v, int soff, int ii) +pr_bitrange(uint32_t v, int soff, int ii) { int off; int i; @@ -1975,16 +1976,16 @@ } static void -pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen) +pr_suptypes(struct icmp6_nodeinfo *ni, int nilen) /* ni->qtype must be SUPTYPES */ { size_t clen; - u_int32_t v; + uint32_t v; const u_char *cp, *end; - u_int16_t cur; + uint16_t cur; struct cbit { - u_int16_t words; /*32bit count*/ - u_int16_t skip; + uint16_t words; /*32bit count*/ + uint16_t skip; } cbit; #define MAXQTYPES (1 << 16) size_t off; @@ -2027,7 +2028,7 @@ for (off = 0; off < clen; off += sizeof(v)) { memcpy(&v, cp + off, sizeof(v)); - v = (u_int32_t)ntohl(v); + v = (uint32_t)ntohl(v); b = pr_bitrange(v, (int)(cur + off * 8), b); } /* flush the remaining bits */ @@ -2072,16 +2073,16 @@ * by the length of the data, but note that the detection algorithm * is incomplete. We assume the latest draft by default. */ - if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0) + if (nilen % (sizeof(uint32_t) + sizeof(struct in6_addr)) == 0) withttl = 1; while (nilen > 0) { - u_int32_t ttl; + uint32_t ttl; if (withttl) { /* XXX: alignment? */ - ttl = (u_int32_t)ntohl(*(u_int32_t *)cp); - cp += sizeof(u_int32_t); - nilen -= sizeof(u_int32_t); + ttl = (uint32_t)ntohl(*(uint32_t *)cp); + cp += sizeof(uint32_t); + nilen -= sizeof(uint32_t); } if (inet_ntop(AF_INET6, cp, ntop_buf, sizeof(ntop_buf)) == @@ -2358,7 +2359,7 @@ break; } (void)printf("pointer = 0x%02x\n", - (u_int32_t)ntohl(icp->icmp6_pptr)); + (uint32_t)ntohl(icp->icmp6_pptr)); pr_retip((struct ip6_hdr *)(icp + 1), end); break; case ICMP6_ECHO_REQUEST: @@ -2517,8 +2518,8 @@ static void pr_iph(struct ip6_hdr *ip6) { - u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; - u_int8_t tc; + uint32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; + u_char tc; char ntop_buf[INET6_ADDRSTRLEN]; tc = *(&ip6->ip6_vfc + 1); /* XXX */ @@ -2527,7 +2528,7 @@ printf("Vr TC Flow Plen Nxt Hlim\n"); printf(" %1x %02x %05x %04x %02x %02x\n", - (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (u_int32_t)ntohl(flow), + (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (uint32_t)ntohl(flow), ntohs(ip6->ip6_plen), ip6->ip6_nxt, ip6->ip6_hlim); if (!inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf))) strlcpy(ntop_buf, "?", sizeof(ntop_buf)); @@ -2567,7 +2568,7 @@ u_char *cp = (u_char *)ip6, nh; int hlen; - if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) { + if (end - (u_char *)ip6 < (ptrdiff_t)sizeof(*ip6)) { printf("IP6"); goto trunc; } @@ -2660,7 +2661,7 @@ /* xxx */ if (ii > 0) for (kk = 0; - (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii; + kk <= MAXDATALEN - 8 + (int)sizeof(struct tv32) + ii; kk += ii) for (jj = 0; jj < ii; ++jj) bp[jj + kk] = pat[jj]; @@ -2701,8 +2702,8 @@ char *p; char *q; MD5_CTX ctxt; - u_int8_t digest[16]; - u_int8_t c; + u_char digest[16]; + u_char c; size_t l; char hbuf[NI_MAXHOST]; struct in6_addr in6; ----Next_Part(Mon_Oct_20_16_29_07_2014_483)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ping.c_20141020-1.diff" Index: ping.c =================================================================== --- ping.c (revision 273295) +++ ping.c (working copy) @@ -1150,8 +1150,7 @@ #endif tp = (const char *)tp + phdr_len; - if ((size_t)(cc - ICMP_MINLEN - phdr_len) >= - sizeof(tv1)) { + if (cc - ICMP_MINLEN - phdr_len >= (int)sizeof(tv1)) { /* Copy to avoid alignment problems: */ memcpy(&tv32, tp, sizeof(tv32)); tv1.tv_sec = ntohl(tv32.tv32_sec); ----Next_Part(Mon_Oct_20_16_29_07_2014_483)---- ----Security_Multipart0(Mon_Oct_20_16_29_08_2014_920)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlREucQACgkQTyzT2CeTzy0jVgCdGyvQeygiqdT6YEwEeLjZNu3b vlQAn0B5WipasyJUBlhUvaN+KfxKpgE5 =KA1u -----END PGP SIGNATURE----- ----Security_Multipart0(Mon_Oct_20_16_29_08_2014_920)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20141020.162907.106891462107570268.hrs>