From 052aa0fcf3f6732e9e33ab63d27431adb4f03c06 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sat, 5 Jul 2025 18:11:34 +0100 Subject: [PATCH] Fix bounds checking in check_ia() A malformed DHCP request can cause out-bounds memory reads, and probably SEGV. --- src/rfc3315.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/rfc3315.c b/src/rfc3315.c index 701bd9a..1a257d9 100644 --- a/src/rfc3315.c +++ b/src/rfc3315.c @@ -1593,9 +1593,14 @@ static void get_context_tag(struct state *state, struct dhcp_context *context) static int check_ia(struct state *state, void *opt, void **endp, void **ia_option) { - state->ia_type = opt6_type(opt); *ia_option = NULL; + /* must be a minimal option to check without stepping outside received packet. */ + if (opt6_ptr(opt, 4) > state->end) + return 0; + + state->ia_type = opt6_type(opt); + if (state->ia_type != OPTION6_IA_NA && state->ia_type != OPTION6_IA_TA) return 0; @@ -1605,7 +1610,10 @@ static int check_ia(struct state *state, void *opt, void **endp, void **ia_optio if (state->ia_type == OPTION6_IA_TA && opt6_len(opt) < 4) return 0; - *endp = opt6_ptr(opt, opt6_len(opt)); + /* Check we don't overflow the received packet. */ + if ((*endp = opt6_ptr(opt, opt6_len(opt))) > state->end) + return 0; + state->iaid = opt6_uint(opt, 0, 4); *ia_option = opt6_find(opt6_ptr(opt, state->ia_type == OPTION6_IA_NA ? 12 : 4), *endp, OPTION6_IAADDR, 24);