diff --git a/ChangeLog b/ChangeLog index 943e6d89a..e7d4ce4cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-10-20 Vladimir Serbinenko + + * grub-core/net/arp.c: Remove variable length arrays. + * grub-core/net/bootp.c: Likewise. + * grub-core/net/dns.c: Likewise. + * grub-core/net/icmp6.c: Likewise. + * grub-core/net/net.c: Likewise. + 2013-10-20 Vladimir Serbinenko * grub-core/fs/ntfs.c: Remove variable length arrays. diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index a34aecd0a..81ce9c3f2 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -163,17 +163,20 @@ grub_net_arp_receive (struct grub_net_buff *nb, { grub_net_link_level_address_t target; /* We've already checked that pln is either 4 or 16. */ - char tmp[arp_header->pln]; + char tmp[16]; + grub_size_t pln = arp_header->pln; + + if (pln > 16) + pln = 16; target.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; grub_memcpy (target.mac, sender_hardware_address, 6); grub_memcpy (target_hardware_address, target.mac, 6); grub_memcpy (sender_hardware_address, inf->hwaddress.mac, 6); - grub_memcpy (tmp, sender_protocol_address, arp_header->pln); - grub_memcpy (sender_protocol_address, target_protocol_address, - arp_header->pln); - grub_memcpy (target_protocol_address, tmp, arp_header->pln); + grub_memcpy (tmp, sender_protocol_address, pln); + grub_memcpy (sender_protocol_address, target_protocol_address, pln); + grub_memcpy (target_protocol_address, tmp, pln); /* Change operation to REPLY and send packet */ arp_header->op = grub_be_to_cpu16 (ARP_REPLY); diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index 72edc2124..2c5a35b6c 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -37,10 +37,11 @@ set_env_limn_ro (const char *intername, const char *suffix, char *value, grub_size_t len) { char c; - char varname[sizeof ("net_") + grub_strlen (intername) + sizeof ("_") - + grub_strlen (suffix)]; + char *varname; char *ptr; - grub_snprintf (varname, sizeof (varname), "net_%s_%s", intername, suffix); + varname = grub_xasprintf ("net_%s_%s", intername, suffix); + if (!varname) + return; for (ptr = varname; *ptr; ptr++) if (*ptr == ':') *ptr = '_'; @@ -50,6 +51,7 @@ set_env_limn_ro (const char *intername, const char *suffix, value[len] = c; grub_register_variable_hook (varname, 0, grub_env_write_readonly); grub_env_export (varname); + grub_free (varname); } static void @@ -100,15 +102,17 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) { grub_net_network_level_netaddress_t target; grub_net_network_level_address_t gw; - char rname[grub_strlen (name) + sizeof (":default")]; + char *rname; target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; target.ipv4.base = 0; target.ipv4.masksize = 0; gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; grub_memcpy (&gw.ipv4, ptr, sizeof (gw.ipv4)); - grub_snprintf (rname, sizeof (rname), "%s:default", name); - grub_net_add_route_gw (rname, target, gw); + rname = grub_xasprintf ("%s:default", name); + if (rname) + grub_net_add_route_gw (rname, target, gw); + grub_free (rname); } break; case GRUB_NET_BOOTP_DNS: @@ -181,15 +185,17 @@ grub_net_configure_by_dhcp_ack (const char *name, { grub_net_network_level_netaddress_t target; grub_net_network_level_address_t gw; - char rname[grub_strlen (name) + sizeof (":gw")]; + char *rname; target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; target.ipv4.base = bp->server_ip; target.ipv4.masksize = 32; gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; gw.ipv4 = bp->gateway_ip; - grub_snprintf (rname, sizeof (rname), "%s:gw", name); - grub_net_add_route_gw (rname, target, gw); + rname = grub_xasprintf ("%s:gw", name); + if (rname) + grub_net_add_route_gw (rname, target, gw); + grub_free (rname); target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; target.ipv4.base = bp->gateway_ip; diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c index 3381ea7ce..0c1da759a 100644 --- a/grub-core/net/dns.c +++ b/grub-core/net/dns.c @@ -421,7 +421,7 @@ grub_net_dns_lookup (const char *name, grub_size_t send_servers = 0; grub_size_t i, j; struct grub_net_buff *nb; - grub_net_udp_socket_t sockets[n_servers]; + grub_net_udp_socket_t *sockets; grub_uint8_t *optr; const char *iptr; struct dns_header *head; @@ -463,9 +463,16 @@ grub_net_dns_lookup (const char *name, } } + sockets = grub_malloc (sizeof (sockets[0]) * n_servers); + if (!sockets) + return grub_errno; + data.name = grub_strdup (name); if (!data.name) - return grub_errno; + { + grub_free (sockets); + return grub_errno; + } nb = grub_netbuff_alloc (GRUB_NET_OUR_MAX_IP_HEADER_SIZE + GRUB_NET_MAX_LINK_HEADER_SIZE @@ -475,6 +482,7 @@ grub_net_dns_lookup (const char *name, + 2 + 4); if (!nb) { + grub_free (sockets); grub_free (data.name); return grub_errno; } @@ -493,6 +501,7 @@ grub_net_dns_lookup (const char *name, dot = iptr + grub_strlen (iptr); if ((dot - iptr) >= 64) { + grub_free (sockets); grub_free (data.name); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("domain name component is too long")); @@ -584,6 +593,8 @@ grub_net_dns_lookup (const char *name, for (j = 0; j < send_servers; j++) grub_net_udp_close (sockets[j]); + grub_free (sockets); + if (*data.naddresses) return GRUB_ERR_NONE; if (data.dns_err) diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c index 9ded94b56..a1bd0782c 100644 --- a/grub-core/net/icmp6.c +++ b/grub-core/net/icmp6.c @@ -412,14 +412,19 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, grub_dprintf ("net", "creating slaac\n"); { - char name[grub_strlen (slaac->name) - + sizeof (":XXXXXXXXXXXXXXXXXXXX")]; - grub_snprintf (name, sizeof (name), "%s:%d", - slaac->name, slaac->slaac_counter++); + char *name; + name = grub_xasprintf ("%s:%d", + slaac->name, slaac->slaac_counter++); + if (!name) + { + grub_errno = GRUB_ERR_NONE; + continue; + } inf = grub_net_add_addr (name, card, &addr, &slaac->address, 0); grub_net_add_route (name, netaddr, inf); + grub_free (name); } } } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 481031990..da50cbffe 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -243,17 +243,68 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card, return slaac; } +static void +grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter); + +static struct grub_net_network_level_interface * +grub_net_add_addr_real (char *name, + struct grub_net_card *card, + const grub_net_network_level_address_t *addr, + const grub_net_link_level_address_t *hwaddress, + grub_net_interface_flags_t flags) +{ + struct grub_net_network_level_interface *inter; + + inter = grub_zalloc (sizeof (*inter)); + if (!inter) + return NULL; + + inter->name = name; + grub_memcpy (&(inter->address), addr, sizeof (inter->address)); + grub_memcpy (&(inter->hwaddress), hwaddress, sizeof (inter->hwaddress)); + inter->flags = flags; + inter->card = card; + inter->dhcp_ack = NULL; + inter->dhcp_acklen = 0; + + grub_net_network_level_interface_register (inter); + + return inter; +} + +struct grub_net_network_level_interface * +grub_net_add_addr (const char *name, + struct grub_net_card *card, + const grub_net_network_level_address_t *addr, + const grub_net_link_level_address_t *hwaddress, + grub_net_interface_flags_t flags) +{ + char *name_dup = grub_strdup (name); + struct grub_net_network_level_interface *ret; + + if (!name_dup) + return NULL; + ret = grub_net_add_addr_real (name_dup, card, addr, hwaddress, flags); + if (!ret) + grub_free (name_dup); + return ret; +} + struct grub_net_network_level_interface * grub_net_ipv6_get_link_local (struct grub_net_card *card, const grub_net_link_level_address_t *hwaddr) { struct grub_net_network_level_interface *inf; - char name[grub_strlen (card->name) - + GRUB_NET_MAX_STR_HWADDR_LEN - + sizeof (":link")]; + char *name; char *ptr; grub_net_network_level_address_t addr; + name = grub_malloc (grub_strlen (card->name) + + GRUB_NET_MAX_STR_HWADDR_LEN + + sizeof (":link")); + if (!name) + return NULL; + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; addr.ipv6[0] = grub_cpu_to_be64 (0xfe80ULL << 48); addr.ipv6[1] = grub_net_ipv6_get_id (hwaddr); @@ -274,7 +325,7 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card, ptr += grub_strlen (ptr); } ptr = grub_stpcpy (ptr, ":link"); - return grub_net_add_addr (name, card, &addr, hwaddr, 0); + return grub_net_add_addr_real (name, card, &addr, hwaddr, 0); } /* FIXME: allow to specify mac address. */ @@ -882,30 +933,36 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa { { char buf[GRUB_NET_MAX_STR_HWADDR_LEN]; - char name[grub_strlen (inter->name) + sizeof ("net__mac")]; + char *name; char *ptr; grub_net_hwaddr_to_str (&inter->hwaddress, buf); - grub_snprintf (name, sizeof (name), "net_%s_mac", inter->name); + name = grub_xasprintf ("net_%s_mac", inter->name); + if (!name) + return; for (ptr = name; *ptr; ptr++) if (*ptr == ':') *ptr = '_'; grub_env_set (name, buf); grub_register_variable_hook (name, 0, hwaddr_set_env); grub_env_export (name); + grub_free (name); } { char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - char name[grub_strlen (inter->name) + sizeof ("net__ip")]; + char *name; char *ptr; grub_net_addr_to_str (&inter->address, buf); - grub_snprintf (name, sizeof (name), "net_%s_ip", inter->name); + name = grub_xasprintf ("net_%s_ip", inter->name); + if (!name) + return; for (ptr = name; *ptr; ptr++) if (*ptr == ':') *ptr = '_'; grub_env_set (name, buf); grub_register_variable_hook (name, 0, addr_set_env); grub_env_export (name); + grub_free (name); } inter->card->num_ifaces++; @@ -916,31 +973,6 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa grub_net_network_level_interfaces = inter; } -struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, - struct grub_net_card *card, - const grub_net_network_level_address_t *addr, - const grub_net_link_level_address_t *hwaddress, - grub_net_interface_flags_t flags) -{ - struct grub_net_network_level_interface *inter; - - inter = grub_zalloc (sizeof (*inter)); - if (!inter) - return NULL; - - inter->name = grub_strdup (name); - grub_memcpy (&(inter->address), addr, sizeof (inter->address)); - grub_memcpy (&(inter->hwaddress), hwaddress, sizeof (inter->hwaddress)); - inter->flags = flags; - inter->card = card; - inter->dhcp_ack = NULL; - inter->dhcp_acklen = 0; - - grub_net_network_level_interface_register (inter); - - return inter; -} grub_err_t grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter,