From 4550e67ae50299f6f69457578162840c2c125d30 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Wed, 14 Nov 2012 10:13:12 +0000 Subject: [PATCH] If we receive a packet with two options the same which is not supposed to be an array then we now trim to the correct size rather than just discarding the option. This also means that if any garbage at the end of the singule occurance of an option is also discarded. --- dhcp.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/dhcp.c b/dhcp.c index 742e352d..9943e042 100644 --- a/dhcp.c +++ b/dhcp.c @@ -253,7 +253,7 @@ int make_option_mask(uint8_t *mask, const char *opts, int add) } static int -valid_length(uint8_t option, int dl, int *type) +validate_length(uint8_t option, int dl, int *type) { const struct dhcp_opt *opt; ssize_t sz; @@ -283,17 +283,20 @@ valid_length(uint8_t option, int dl, int *type) if (opt->type & UINT8) sz = sizeof(uint8_t); /* If we don't know the size, assume it's valid */ - return (sz == 0 || dl == sz ? 0 : -1); + if (sz == 0) + return dl; + return sz; } /* unknown option, so let it pass */ - return 0; + return dl; } #ifdef DEBUG_MEMORY static void free_option_buffer(void) { + free(opt_buffer); } #endif @@ -309,7 +312,7 @@ get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type) uint8_t overl = 0; uint8_t *bp = NULL; const uint8_t *op = NULL; - int bl = 0; + ssize_t bl = 0; while (p < e) { o = *p++; @@ -358,7 +361,9 @@ get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len, int *type) } exit: - if (valid_length(opt, bl, type) == -1) { + + bl = validate_length(opt, bl, type); + if (bl == -1) { errno = EINVAL; return NULL; } -- 2.47.2