diff options
Diffstat (limited to 'libdhcp/dhcp_client.c')
-rw-r--r-- | libdhcp/dhcp_client.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/libdhcp/dhcp_client.c b/libdhcp/dhcp_client.c index 2d0ebe6..2c9bd40 100644 --- a/libdhcp/dhcp_client.c +++ b/libdhcp/dhcp_client.c @@ -312,7 +312,9 @@ static bool dhcp_client_send(struct dhcp_client *client, uint8_t msgtyp, const c switch (msgtyp) { case DHCP_MSGTYP_DISCOVER: case DHCP_MSGTYP_INFORM: case DHCP_MSGTYP_REQUEST: - secs = (LO_CALL(bootclock, get_time_ns) - client->time_ns_init)/NS_PER_S; + uint64_t secs64 = (LO_CALL(bootclock, get_time_ns) - client->time_ns_init)/NS_PER_S; + assert(secs64 < UINT16_MAX); /* 18 hours */ + secs = LM_SAFEDOWNCAST(uint16_t, secs64); if (!secs) /* systemd's sd-dhcp-client.c asserts that some * servers are broken and require .secs to be @@ -438,15 +440,16 @@ static bool dhcp_client_send(struct dhcp_client *client, uint8_t msgtyp, const c assert(val.len); if (val.len) { assert(val.len <= UINT16_MAX); - for (size_t done = 0; done < val.len;) { - uint8_t len = val.len - done > UINT8_MAX + uint16_t len16 = (uint16_t)val.len; + for (uint16_t done = 0; done < len16;) { + uint8_t len8 = (len16 - done > UINT8_MAX) ? UINT8_MAX - : val.len - done; + : LM_SAFEDOWNCAST(uint8_t, len16 - done); scratch_msg->options[optlen++] = opt; - scratch_msg->options[optlen++] = len; - memcpy(&scratch_msg->options[optlen], &((char*)val.ptr)[done], len); - optlen += len; - done += len; + scratch_msg->options[optlen++] = len8; + memcpy(&scratch_msg->options[optlen], &((char*)val.ptr)[done], len8); + optlen += len8; + done += len8; } } break; @@ -484,7 +487,8 @@ struct dhcp_recv_msg { /** @return whether there is an error */ static inline bool _dhcp_client_recv_measure_opts(struct dhcp_recv_msg *ret, uint8_t *optoverload, uint8_t *dat, size_t len, bool require_pad) { - for (size_t pos = 0, opt_len; pos < len; pos += opt_len) { + uint8_t opt_len; + for (size_t pos = 0; pos < len; pos += opt_len) { uint8_t opt_typ = dat[pos++]; switch (opt_typ) { case DHCP_OPT_END: @@ -511,7 +515,8 @@ static inline bool _dhcp_client_recv_measure_opts(struct dhcp_recv_msg *ret, uin } static inline void _dhcp_client_recv_consolidate_opts(struct dhcp_recv_msg *ret, uint8_t *dat, size_t len) { - for (size_t pos = 0, opt_len; pos < len; pos += opt_len) { + uint8_t opt_len; + for (size_t pos = 0; pos < len; pos += opt_len) { uint8_t opt_typ = dat[pos++]; switch (opt_typ) { case DHCP_OPT_END: @@ -573,15 +578,17 @@ static inline enum requirement dhcp_table3(uint8_t req_msgtyp, uint8_t resp_msgt static ssize_t dhcp_client_recv(struct dhcp_client *client, struct dhcp_recv_msg *ret) { struct net_ip4_addr srv_addr; uint16_t srv_port; - ssize_t msg_len; + ssize_t _msg_len; + size_t msg_len; assert(client); ignore: - msg_len = LO_CALL(client->sock, recvfrom, &ret->raw, sizeof(ret->raw), &srv_addr, &srv_port); - if (msg_len < 0) + _msg_len = LO_CALL(client->sock, recvfrom, &ret->raw, sizeof(ret->raw), &srv_addr, &srv_port); + if (_msg_len < 0) /* msg_len is -errno */ - return msg_len; + return _msg_len; + msg_len = LM_SAFEDOWNCAST(size_t, _msg_len); /* Validate L3: IP */ /* Don't validate that srv_addr matches client->server_id @@ -594,10 +601,10 @@ static ssize_t dhcp_client_recv(struct dhcp_client *client, struct dhcp_recv_msg goto ignore; /* Validate L5: DHCP. */ - if ((size_t)msg_len < DHCP_MSG_BASE_SIZE + sizeof(dhcp_magic_cookie)) + if (msg_len < DHCP_MSG_BASE_SIZE + sizeof(dhcp_magic_cookie)) /* ignore impossibly short message */ goto ignore; - if ((size_t)msg_len > sizeof(ret->raw)) + if (msg_len > sizeof(ret->raw)) /* ignore message that is larger than the specified * DHCP_OPT_DHCP_MAX_MSG_SIZE */ goto ignore; @@ -646,7 +653,8 @@ static ssize_t dhcp_client_recv(struct dhcp_client *client, struct dhcp_recv_msg true)) goto ignore; /* Validate sizes, allocate buffers. */ - for (uint8_t opt = 1, allocated = 0; opt < 255; opt++) { + uint16_t allocated = 0; + for (uint8_t opt = 1; opt < 255; opt++) { if (!ret->options[opt].len) continue; if (!dhcp_opt_length_is_valid(opt, ret->options[opt].len)) |