diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-17 18:07:18 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-17 18:07:18 +0100 |
| commit | 6d3b4bb24da9a07c263f3c1acf8df85382ff562c (patch) | |
| tree | 62b1094f93c955774e8b2d4aee798029a5a71b7d | |
| parent | 4b72aebe80aaa50a765d5ff61d7d67ed731502d9 (diff) | |
| download | busybox-w32-6d3b4bb24da9a07c263f3c1acf8df85382ff562c.tar.gz busybox-w32-6d3b4bb24da9a07c263f3c1acf8df85382ff562c.tar.bz2 busybox-w32-6d3b4bb24da9a07c263f3c1acf8df85382ff562c.zip | |
udhcpc: check that 4-byte options are indeed 4-byte, closes 11506
function old new delta
udhcp_get_option32 - 27 +27
udhcp_get_option 231 248 +17
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 44/0) Total: 44 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | networking/udhcp/common.c | 19 | ||||
| -rw-r--r-- | networking/udhcp/common.h | 4 | ||||
| -rw-r--r-- | networking/udhcp/dhcpc.c | 6 | ||||
| -rw-r--r-- | networking/udhcp/dhcpd.c | 6 |
4 files changed, 29 insertions, 6 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index e5fd74f91..41b05b855 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
| @@ -272,6 +272,15 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
| 272 | goto complain; /* complain and return NULL */ | 272 | goto complain; /* complain and return NULL */ |
| 273 | 273 | ||
| 274 | if (optionptr[OPT_CODE] == code) { | 274 | if (optionptr[OPT_CODE] == code) { |
| 275 | if (optionptr[OPT_LEN] == 0) { | ||
| 276 | /* So far no valid option with length 0 known. | ||
| 277 | * Having this check means that searching | ||
| 278 | * for DHCP_MESSAGE_TYPE need not worry | ||
| 279 | * that returned pointer might be unsafe | ||
| 280 | * to dereference. | ||
| 281 | */ | ||
| 282 | goto complain; /* complain and return NULL */ | ||
| 283 | } | ||
| 275 | log_option("option found", optionptr); | 284 | log_option("option found", optionptr); |
| 276 | return optionptr + OPT_DATA; | 285 | return optionptr + OPT_DATA; |
| 277 | } | 286 | } |
| @@ -289,6 +298,16 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
| 289 | return NULL; | 298 | return NULL; |
| 290 | } | 299 | } |
| 291 | 300 | ||
| 301 | uint8_t* FAST_FUNC udhcp_get_option32(struct dhcp_packet *packet, int code) | ||
| 302 | { | ||
| 303 | uint8_t *r = udhcp_get_option(packet, code); | ||
| 304 | if (r) { | ||
| 305 | if (r[-1] != 4) | ||
| 306 | r = NULL; | ||
| 307 | } | ||
| 308 | return r; | ||
| 309 | } | ||
| 310 | |||
| 292 | /* Return the position of the 'end' option (no bounds checking) */ | 311 | /* Return the position of the 'end' option (no bounds checking) */ |
| 293 | int FAST_FUNC udhcp_end_option(uint8_t *optionptr) | 312 | int FAST_FUNC udhcp_end_option(uint8_t *optionptr) |
| 294 | { | 313 | { |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 7ad603d33..9511152ff 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
| @@ -205,6 +205,10 @@ extern const uint8_t dhcp_option_lengths[] ALIGN1; | |||
| 205 | unsigned FAST_FUNC udhcp_option_idx(const char *name, const char *option_strings); | 205 | unsigned FAST_FUNC udhcp_option_idx(const char *name, const char *option_strings); |
| 206 | 206 | ||
| 207 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; | 207 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; |
| 208 | /* Same as above + ensures that option length is 4 bytes | ||
| 209 | * (returns NULL if size is different) | ||
| 210 | */ | ||
| 211 | uint8_t *udhcp_get_option32(struct dhcp_packet *packet, int code) FAST_FUNC; | ||
| 208 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; | 212 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; |
| 209 | void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; | 213 | void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; |
| 210 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | 214 | #if ENABLE_UDHCPC || ENABLE_UDHCPD |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 4b23e4d39..5b3fd531c 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
| @@ -1691,7 +1691,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1691 | * They say ISC DHCP client supports this case. | 1691 | * They say ISC DHCP client supports this case. |
| 1692 | */ | 1692 | */ |
| 1693 | server_addr = 0; | 1693 | server_addr = 0; |
| 1694 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1694 | temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
| 1695 | if (!temp) { | 1695 | if (!temp) { |
| 1696 | bb_error_msg("no server ID, using 0.0.0.0"); | 1696 | bb_error_msg("no server ID, using 0.0.0.0"); |
| 1697 | } else { | 1697 | } else { |
| @@ -1718,7 +1718,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1718 | struct in_addr temp_addr; | 1718 | struct in_addr temp_addr; |
| 1719 | uint8_t *temp; | 1719 | uint8_t *temp; |
| 1720 | 1720 | ||
| 1721 | temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); | 1721 | temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); |
| 1722 | if (!temp) { | 1722 | if (!temp) { |
| 1723 | bb_error_msg("no lease time with ACK, using 1 hour lease"); | 1723 | bb_error_msg("no lease time with ACK, using 1 hour lease"); |
| 1724 | lease_seconds = 60 * 60; | 1724 | lease_seconds = 60 * 60; |
| @@ -1813,7 +1813,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1813 | uint32_t svid; | 1813 | uint32_t svid; |
| 1814 | uint8_t *temp; | 1814 | uint8_t *temp; |
| 1815 | 1815 | ||
| 1816 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1816 | temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
| 1817 | if (!temp) { | 1817 | if (!temp) { |
| 1818 | non_matching_svid: | 1818 | non_matching_svid: |
| 1819 | log1("received DHCP NAK with wrong" | 1819 | log1("received DHCP NAK with wrong" |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index a8cd3f03b..477856d11 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
| @@ -640,7 +640,7 @@ static void add_server_options(struct dhcp_packet *packet) | |||
| 640 | static uint32_t select_lease_time(struct dhcp_packet *packet) | 640 | static uint32_t select_lease_time(struct dhcp_packet *packet) |
| 641 | { | 641 | { |
| 642 | uint32_t lease_time_sec = server_config.max_lease_sec; | 642 | uint32_t lease_time_sec = server_config.max_lease_sec; |
| 643 | uint8_t *lease_time_opt = udhcp_get_option(packet, DHCP_LEASE_TIME); | 643 | uint8_t *lease_time_opt = udhcp_get_option32(packet, DHCP_LEASE_TIME); |
| 644 | if (lease_time_opt) { | 644 | if (lease_time_opt) { |
| 645 | move_from_unaligned32(lease_time_sec, lease_time_opt); | 645 | move_from_unaligned32(lease_time_sec, lease_time_opt); |
| 646 | lease_time_sec = ntohl(lease_time_sec); | 646 | lease_time_sec = ntohl(lease_time_sec); |
| @@ -987,7 +987,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | /* Get SERVER_ID if present */ | 989 | /* Get SERVER_ID if present */ |
| 990 | server_id_opt = udhcp_get_option(&packet, DHCP_SERVER_ID); | 990 | server_id_opt = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
| 991 | if (server_id_opt) { | 991 | if (server_id_opt) { |
| 992 | uint32_t server_id_network_order; | 992 | uint32_t server_id_network_order; |
| 993 | move_from_unaligned32(server_id_network_order, server_id_opt); | 993 | move_from_unaligned32(server_id_network_order, server_id_opt); |
| @@ -1011,7 +1011,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 1011 | } | 1011 | } |
| 1012 | 1012 | ||
| 1013 | /* Get REQUESTED_IP if present */ | 1013 | /* Get REQUESTED_IP if present */ |
| 1014 | requested_ip_opt = udhcp_get_option(&packet, DHCP_REQUESTED_IP); | 1014 | requested_ip_opt = udhcp_get_option32(&packet, DHCP_REQUESTED_IP); |
| 1015 | if (requested_ip_opt) { | 1015 | if (requested_ip_opt) { |
| 1016 | move_from_unaligned32(requested_nip, requested_ip_opt); | 1016 | move_from_unaligned32(requested_nip, requested_ip_opt); |
| 1017 | } | 1017 | } |
