summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2016-01-28 01:59:14 +0000
committerBen Hutchings <ben@decadent.org.uk>2016-01-28 15:48:22 +0000
commitecb466590600a2442d167c8b4b80d6c545e63134 (patch)
tree1f40605cd4f6b6d3d51f2a041e03ebc932f53ad5 /src
parent687b3c65c0460dd8c4ba7e63e3ae0ab20836e6e8 (diff)
downloadodhcp6c-ecb466590600a2442d167c8b4b80d6c545e63134.tar.gz
Fix unaligned 32-bit reads from DHCP packets
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'src')
-rw-r--r--src/dhcpv6.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index 8a1231d..cbf6991 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -110,6 +110,14 @@ static uint8_t reconf_key[16];
static unsigned int client_options = 0;
+static uint32_t ntohl_unaligned(const uint8_t *data)
+{
+ uint32_t buf;
+
+ memcpy(&buf, data, sizeof(buf));
+ return ntohl(buf);
+}
+
int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout)
{
client_options = options;
@@ -806,12 +814,12 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc,
} else if (otype == DHCPV6_OPT_RECONF_ACCEPT) {
cand.wants_reconfigure = true;
} else if (otype == DHCPV6_OPT_SOL_MAX_RT && olen == 4) {
- uint32_t sol_max_rt = ntohl(*((uint32_t *)odata));
+ uint32_t sol_max_rt = ntohl_unaligned(odata);
if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN &&
sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX)
cand.sol_max_rt = sol_max_rt;
} else if (otype == DHCPV6_OPT_INF_MAX_RT && olen == 4) {
- uint32_t inf_max_rt = ntohl(*((uint32_t *)odata));
+ uint32_t inf_max_rt = ntohl_unaligned(odata);
if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN &&
inf_max_rt <= DHCPV6_INF_MAX_RT_MAX)
cand.inf_max_rt = inf_max_rt;
@@ -1029,7 +1037,7 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
} else if (otype == DHCPV6_OPT_SIP_SERVER_D) {
odhcp6c_add_state(STATE_SIP_FQDN, odata, olen);
} else if (otype == DHCPV6_OPT_INFO_REFRESH && olen >= 4) {
- refresh = ntohl(*((uint32_t*)odata));
+ refresh = ntohl_unaligned(odata);
passthru = false;
} else if (otype == DHCPV6_OPT_AUTH) {
if (olen == -4 + sizeof(struct dhcpv6_auth_reconfigure)) {
@@ -1046,13 +1054,13 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
odhcp6c_add_state(STATE_AFTR_NAME, odata, olen);
passthru = false;
} else if (otype == DHCPV6_OPT_SOL_MAX_RT && olen == 4) {
- uint32_t sol_max_rt = ntohl(*((uint32_t *)odata));
+ uint32_t sol_max_rt = ntohl_unaligned(odata);
if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN &&
sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX)
dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_max_rt;
passthru = false;
} else if (otype == DHCPV6_OPT_INF_MAX_RT && olen == 4) {
- uint32_t inf_max_rt = ntohl(*((uint32_t *)odata));
+ uint32_t inf_max_rt = ntohl_unaligned(odata);
if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN &&
inf_max_rt <= DHCPV6_INF_MAX_RT_MAX)
dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = inf_max_rt;