From: Roy Marples Date: Sat, 28 Mar 2015 20:34:18 +0000 (+0000) Subject: Fix more htons and uint16_t issues. X-Git-Tag: v6.8.2~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e4ea3a498300775751b8eff96972fa5b7feea45;p=thirdparty%2Fdhcpcd.git Fix more htons and uint16_t issues. Thanks to Christos. --- diff --git a/dhcp.c b/dhcp.c index 13ac7dac..704c3260 100644 --- a/dhcp.c +++ b/dhcp.c @@ -698,10 +698,10 @@ make_message(struct dhcp_message **message, { struct dhcp_message *dhcp; uint8_t *m, *lp, *p, *auth; - uint8_t *n_params = NULL; + uint8_t *n_params = NULL, auth_len; uint32_t ul; uint16_t sz; - size_t len, i, auth_len; + size_t len, i; const struct dhcp_opt *opt; struct if_options *ifo = ifp->options; const struct dhcp_state *state = D_CSTATE(ifp); @@ -749,7 +749,7 @@ make_message(struct dhcp_message **message, if (up < 0 || up > (time_t)UINT16_MAX) dhcp->secs = htons((uint16_t)UINT16_MAX); else - dhcp->secs = htons(up); + dhcp->secs = htons((uint16_t)up); } dhcp->xid = htonl(state->xid); dhcp->cookie = htonl(MAGIC_COOKIE); @@ -825,7 +825,7 @@ make_message(struct dhcp_message **message, * handle DHCP packets any bigger. */ mtu = MTU_MAX; } - sz = htons(mtu); + sz = htons((uint16_t)mtu); memcpy(p, &sz, 2); p += 2; @@ -1001,19 +1001,23 @@ make_message(struct dhcp_message **message, auth = NULL; if (ifo->auth.options & DHCPCD_AUTH_SEND) { - auth_len = (size_t)dhcp_auth_encode(&ifo->auth, + ssize_t alen = dhcp_auth_encode(&ifo->auth, state->auth.token, NULL, 0, 4, type, NULL, 0); - if ((ssize_t)auth_len == -1) { + if (alen != -1 && alen > UINT8_MAX) { + errno = ERANGE; + alen = -1; + } + if (alen == -1) logger(ifp->ctx, LOG_ERR, "%s: dhcp_auth_encode: %m", ifp->name); - auth_len = 0; - } else if (auth_len != 0) { - len = (size_t)((p + auth_len) - m); - if (auth_len > 255 || len > sizeof(*dhcp)) + else if (alen != 0) { + auth_len = (uint8_t)alen; + len = (size_t)((p + alen) - m); + if (len > sizeof(*dhcp)) goto toobig; *p++ = DHO_AUTHENTICATION; - *p++ = (uint8_t)auth_len; + *p++ = auth_len; auth = p; p += auth_len; } @@ -1550,7 +1554,7 @@ dhcp_makeudppacket(size_t *sz, const uint8_t *data, size_t length, ip->ip_hl = sizeof(*ip) >> 2; ip->ip_id = (uint16_t)arc4random_uniform(UINT16_MAX); ip->ip_ttl = IPDEFTTL; - ip->ip_len = htons(sizeof(*ip) + sizeof(*udp) + length); + ip->ip_len = htons((uint16_t)(sizeof(*ip) + sizeof(*udp) + length)); ip->ip_sum = checksum(ip, sizeof(*ip)); *sz = sizeof(*ip) + sizeof(*udp) + length; diff --git a/dhcp6.c b/dhcp6.c index c95bee1d..dae1c58d 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -198,14 +198,14 @@ dhcp6_makevendor(struct dhcp6_option *o, const struct interface *ifp) i < ifo->vivco_len; i++, vivco++) { - u16 = htons(vivco->len); + u16 = htons((uint16_t)vivco->len); memcpy(p, &u16, sizeof(u16)); p += sizeof(u16); memcpy(p, vivco->data, vivco->len); p += vivco->len; } } else if (vlen) { - u16 = htons(vlen); + u16 = htons((uint16_t)vlen); memcpy(p, &u16, sizeof(u16)); p += sizeof(u16); memcpy(p, vendor, (size_t)vlen); @@ -494,9 +494,9 @@ dhcp6_makemessage(struct interface *ifp) struct dhcp6_message *m; struct dhcp6_option *o, *so, *eo; const struct dhcp6_option *si, *unicast; - size_t l, n, len, ml, auth_len; + size_t l, n, len, ml; uint8_t u8, type; - uint16_t u16, n_options; + uint16_t u16, n_options, auth_len; struct if_options *ifo; const struct dhcp_opt *opt, *opt2; uint8_t IA, *p; @@ -701,17 +701,22 @@ dhcp6_makemessage(struct interface *ifp) return -1; } + auth_len = 0; if (ifo->auth.options & DHCPCD_AUTH_SEND) { - auth_len = (size_t)dhcp_auth_encode(&ifo->auth, + ssize_t alen = dhcp_auth_encode(&ifo->auth, state->auth.token, NULL, 0, 6, type, NULL, 0); - if ((ssize_t)auth_len == -1) { + if (alen != -1 && alen > UINT16_MAX) { + errno = ERANGE; + alen = -1; + } + if (alen == -1) logger(ifp->ctx, LOG_ERR, "%s: dhcp_auth_encode: %m", ifp->name); - auth_len = 0; - } else if (auth_len != 0) + else if (alen != 0) { + auth_len = (uint16_t)alen; len += sizeof(*o) + auth_len; - } else - auth_len = 0; /* appease GCC */ + } + } state->send = malloc(len); if (state->send == NULL) @@ -731,7 +736,7 @@ dhcp6_makemessage(struct interface *ifp) o = D6_FIRST_OPTION(state->send); o->code = htons(D6_OPTION_CLIENTID); - o->len = htons(ifp->ctx->duid_len); + o->len = htons((uint16_t)ifp->ctx->duid_len); memcpy(D6_OPTION_DATA(o), ifp->ctx->duid, ifp->ctx->duid_len); if (si) { @@ -813,9 +818,9 @@ dhcp6_makemessage(struct interface *ifp) eo->len = htons(eo->len); } - u32 = (uint32_t)(ntohs(o->len) + sizeof(*so) + u16 = (uint16_t)(ntohs(o->len) + sizeof(*so) + ntohs(so->len)); - o->len = htons(u32); + o->len = htons(u16); } else { so->code = htons(D6_OPTION_IA_ADDR); so->len = sizeof(ap->addr) + @@ -852,7 +857,7 @@ dhcp6_makemessage(struct interface *ifp) l = encode_rfc1035(hostname, p + 1); if (l == 0) *p = D6_FQDN_NONE; - o->len = htons(l + 1); + o->len = htons((uint16_t)(l + 1)); } if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) != @@ -886,7 +891,7 @@ dhcp6_makemessage(struct interface *ifp) has_option_mask(ifo->requestmask6, opt->option))) { - u16 = htons(opt->option); + u16 = htons((uint16_t)opt->option); memcpy(p, &u16, sizeof(u16)); p += sizeof(u16); o->len = (uint16_t)(o->len + sizeof(u16)); @@ -901,7 +906,7 @@ dhcp6_makemessage(struct interface *ifp) has_option_mask(ifo->requestmask6, opt->option))) { - u16 = htons(opt->option); + u16 = htons((uint16_t)opt->option); memcpy(p, &u16, sizeof(u16)); p += sizeof(u16); o->len = (uint16_t)(o->len + sizeof(u16)); @@ -920,7 +925,7 @@ dhcp6_makemessage(struct interface *ifp) if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0) { o = D6_NEXT_OPTION(o); o->code = htons(D6_OPTION_AUTH); - o->len = htons(auth_len); + o->len = htons((uint16_t)auth_len); /* data will be filled at send message time */ } diff --git a/ipv6nd.c b/ipv6nd.c index 355a01eb..a58d7ce1 100644 --- a/ipv6nd.c +++ b/ipv6nd.c @@ -1457,7 +1457,7 @@ ipv6nd_handlena(struct dhcpcd_ctx *dctx, struct interface *ifp, struct ipv6_ctx *ctx = dctx->ipv6; struct nd_neighbor_advert *nd_na; struct ra *rap; - int is_router, is_solicited; + uint32_t is_router, is_solicited; char buf[INET6_ADDRSTRLEN]; const char *taddr;