udhcpc6: carry along length of packet when parsing it.
authorDavid Decotigny <ddecotig@gmail.com>
Thu, 24 May 2018 15:30:15 +0000 (08:30 -0700)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 24 May 2018 16:34:56 +0000 (18:34 +0200)
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 <ddecotig@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
networking/udhcp/d6_dhcpc.c

index 2ff9c56695ed0a7212ba5595d83556c0beafb9dd..4dbc2b1bd3215c96b1c0acf287e4faf6bacbbf34 100644 (file)
@@ -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);