udhcpc: check read of option length byte to be within packet
No binary (build failed)
—
(log yok)
| @@ -226,9 +226,12 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |
| rem = sizeof(packet->options); | |
| while (1) { | |
| if (rem <= 0) { | |
| + | complain: |
| bb_error_msg("bad packet, malformed option field"); | |
| return NULL; | |
| } | |
| + | |
| + | /* DHCP_PADDING and DHCP_END have no [len] byte */ |
| if (optionptr[OPT_CODE] == DHCP_PADDING) { | |
| rem--; | |
| optionptr++; | |
| @@ -251,10 +254,13 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |
| } | |
| break; | |
| } | |
| + | |
| + | if (rem <= OPT_LEN) |
| + | goto complain; /* complain and return NULL */ |
| len = 2 + optionptr[OPT_LEN]; | |
| rem -= len; | |
| if (rem < 0) | |
| - | continue; /* complain and return NULL */ |
| + | goto complain; /* complain and return NULL */ |
| if (optionptr[OPT_CODE] == code) { | |
| log_option("option found", optionptr); | |
| @@ -450,7 +450,7 @@ static char **fill_envp(struct dhcp_packet *packet) | |
| temp = udhcp_get_option(packet, i); | |
| if (temp) { | |
| if (i == DHCP_OPTION_OVERLOAD) | |
| - | overload = *temp; |
| + | overload |= *temp; |
| else if (i == DHCP_SUBNET) | |
| envc++; /* for $mask */ | |
| envc++; | |
| @@ -476,7 +476,7 @@ static char **fill_envp(struct dhcp_packet *packet) | |
| * uint16_t secs; // elapsed since client began acquisition/renewal | |
| * uint16_t flags; // only one flag so far: bcast. Never set by server | |
| * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different | |
| - | * // if during renew server wants to give us differn IP?) |
| + | * // if during renew server wants to give us different IP?) |
| * uint32_t gateway_nip; // relay agent IP address | |
| * uint8_t chaddr[16]; // link-layer client hardware address (MAC) | |
| * TODO: export gateway_nip as $giaddr? | |