summaryrefslogtreecommitdiff
path: root/src/dhcpv6.c
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2014-10-10 18:18:42 +0600
committerVladislav Grishenko <themiron@mail.ru>2014-10-10 18:21:32 +0600
commit2015de99e2495e886a0e5c748a654d7d5b112cf9 (patch)
tree0e2790a331678eb6b6b24e5ef5723a417a20e942 /src/dhcpv6.c
parent569a7bbe8a181b0e48cb12c751988406de3d7f0b (diff)
downloadodhcp6c-2015de99e2495e886a0e5c748a654d7d5b112cf9.tar.gz
Fix parsing empty IA_NA, IA_PD and invalid IA_ADDR options
Diffstat (limited to 'src/dhcpv6.c')
-rw-r--r--src/dhcpv6.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index 30c9fb2..ca41db6 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -693,7 +693,7 @@ static bool dhcpv6_response_is_valid(const void *buf, ssize_t len,
rcmsg = odata[0];
} else if ((otype == DHCPV6_OPT_IA_PD || otype == DHCPV6_OPT_IA_NA)) {
ia_present = true;
- if (olen < sizeof(struct dhcpv6_ia_hdr))
+ if (olen < -4 + sizeof(struct dhcpv6_ia_hdr))
options_valid = false;
}
else if ((otype == DHCPV6_OPT_IA_ADDR) || (otype == DHCPV6_OPT_IA_PREFIX) ||
@@ -761,7 +761,7 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc,
dhcpv6_for_each_option(opt, end, otype, olen, odata) {
if (orig == DHCPV6_MSG_SOLICIT &&
(otype == DHCPV6_OPT_IA_PD || otype == DHCPV6_OPT_IA_NA) &&
- olen > sizeof(struct dhcpv6_ia_hdr)) {
+ olen > -4 + sizeof(struct dhcpv6_ia_hdr)) {
struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-4]);
dhcpv6_parse_ia(ia_hdr, odata + olen + sizeof(*ia_hdr));
}
@@ -800,8 +800,8 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc,
struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr*)&odata[-4];
uint8_t *oend = odata + olen, *d;
dhcpv6_for_each_option(&h[1], oend, otype, olen, d) {
- if (otype == DHCPV6_OPT_IA_PREFIX && (olen + 4) >=
- (uint16_t)sizeof(struct dhcpv6_ia_prefix)) {
+ if (otype == DHCPV6_OPT_IA_PREFIX &&
+ olen >= -4 + sizeof(struct dhcpv6_ia_prefix)) {
struct dhcpv6_ia_prefix *p = (struct dhcpv6_ia_prefix*)&d[-4];
have_pd = p->prefix;
}
@@ -810,7 +810,8 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc,
struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr*)&odata[-4];
uint8_t *oend = odata + olen, *d;
dhcpv6_for_each_option(&h[1], oend, otype, olen, d)
- if (otype == DHCPV6_OPT_IA_ADDR)
+ if (otype == DHCPV6_OPT_IA_ADDR &&
+ olen >= -4 + sizeof(struct dhcpv6_ia_addr))
have_na = true;
}
}
@@ -930,7 +931,7 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
bool passthru = true;
if ((otype == DHCPV6_OPT_IA_PD || otype == DHCPV6_OPT_IA_NA)
- && olen > sizeof(struct dhcpv6_ia_hdr)) {
+ && olen > -4 + sizeof(struct dhcpv6_ia_hdr)) {
struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-4]);
// Test ID