From 8f48fc01e9e43d16bf5860fa37252b43c76cb395 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Thu, 24 May 2018 08:30:15 -0700 Subject: [PATCH] udhcpc6: carry along length of packet when parsing it. This is to avoid parsing garbage past packet's actual end. Also const-ize params to a few functions. function old new delta d6_run_script_no_option - 12 +12 option_to_env 791 798 +7 d6_run_script 253 255 +2 perform_d6_release 95 93 -2 udhcpc6_main 2596 2592 -4 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/2 up/down: 21/-6) Total: 15 bytes Signed-off-by: David Decotigny Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 2ff9c5669..4dbc2b1bd 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -215,7 +215,8 @@ static char** new_env(void) return &client6_data.env_ptr[client6_data.env_idx++]; } -static char *string_option_to_env(uint8_t *option, uint8_t *option_end) +static char *string_option_to_env(const uint8_t *option, + const uint8_t *option_end) { const char *ptr, *name = NULL; unsigned val_len; @@ -244,7 +245,7 @@ static char *string_option_to_env(uint8_t *option, uint8_t *option_end) } /* put all the parameters into the environment */ -static void option_to_env(uint8_t *option, uint8_t *option_end) +static void option_to_env(const uint8_t *option, const uint8_t *option_end) { #if ENABLE_FEATURE_UDHCPC6_RFC3646 int addrs, option_offset; @@ -422,7 +423,7 @@ static void option_to_env(uint8_t *option, uint8_t *option_end) } } -static char **fill_envp(struct d6_packet *packet) +static char **fill_envp(const uint8_t *option, const uint8_t *option_end) { char **envp, **curr; @@ -431,8 +432,8 @@ static char **fill_envp(struct d6_packet *packet) *new_env() = xasprintf("interface=%s", client_config.interface); - if (packet) - option_to_env(packet->d6_options, packet->d6_options + sizeof(packet->d6_options)); + if (option) + option_to_env(option, option_end); envp = curr = client6_data.env_ptr; while (*curr) @@ -442,12 +443,13 @@ static char **fill_envp(struct d6_packet *packet) } /* Call a script with a par file and env vars */ -static void d6_run_script(struct d6_packet *packet, const char *name) +static void d6_run_script(const uint8_t *option, const uint8_t *option_end, + const char *name) { char **envp, **curr; char *argv[3]; - envp = fill_envp(packet); + envp = fill_envp(option, option_end); /* call script */ log1("executing %s %s", client_config.script, name); @@ -463,6 +465,11 @@ static void d6_run_script(struct d6_packet *packet, const char *name) free(envp); } +/* Call a script with a par file and no env var */ +static void d6_run_script_no_option(const char *name) +{ + d6_run_script(NULL, NULL, name); +} /*** Sending/receiving packets ***/ @@ -1038,7 +1045,7 @@ static void perform_renew(void) state = RENEW_REQUESTED; break; case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ - d6_run_script(NULL, "deconfig"); + d6_run_script_no_option("deconfig"); case REQUESTING: case RELEASED: change_listen_mode(LISTEN_RAW); @@ -1067,7 +1074,7 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou * Users requested to be notified in all cases, even if not in one * of the states above. */ - d6_run_script(NULL, "deconfig"); + d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_NONE); state = RELEASED; } @@ -1276,7 +1283,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) udhcp_sp_setup(); state = INIT_SELECTING; - d6_run_script(NULL, "deconfig"); + d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_RAW); packet_num = 0; timeout = 0; @@ -1357,7 +1364,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) continue; } leasefail: - d6_run_script(NULL, "leasefail"); + d6_run_script_no_option("leasefail"); #if BB_MMU /* -b is not supported on NOMMU */ if (opt & OPT_b) { /* background if no lease */ bb_error_msg("no lease, forking to background"); @@ -1431,7 +1438,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) } /* Timed out, enter init state */ bb_error_msg("lease lost, entering init state"); - d6_run_script(NULL, "deconfig"); + d6_run_script_no_option("deconfig"); state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ /*timeout = 0; - already is */ @@ -1538,9 +1545,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) if (option && (option->data[0] | option->data[1]) != 0) { /* return to init state */ bb_error_msg("received DHCP NAK (%u)", option->data[4]); - d6_run_script(&packet, "nak"); + d6_run_script(packet.d6_options, + packet_end, "nak"); if (state != REQUESTING) - d6_run_script(NULL, "deconfig"); + d6_run_script_no_option("deconfig"); change_listen_mode(LISTEN_RAW); sleep(3); /* avoid excessive network traffic */ state = INIT_SELECTING; @@ -1737,7 +1745,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) if (timeout < 0x10) timeout = 0x10; /* enter bound state */ - d6_run_script(&packet, state == REQUESTING ? "bound" : "renew"); + d6_run_script(packet.d6_options, packet_end, + (state == REQUESTING ? "bound" : "renew")); state = BOUND; change_listen_mode(LISTEN_NONE);