diff --git a/ChangeLog b/ChangeLog index d4694dd75..4ca2fac41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-05-08 Bean + + * grub-core/net/ip.c (reassemble): Make asm_buffer into asm_netbuff. + All users updated. + (free_rsm): Free header as well. + (free_old_fragments): Fix memory leak. + * grub-core/net/netbuff.c (grub_netbuff_free): Make return void. + * grub-core/net/tftp.c (tftp_receive): Fix memory leak. + (destroy_pq): Likewise. + * include/grub/net/netbuff.h (grub_netbuff_free): Make return void. + 2012-05-08 Vladimir Serbinenko * grub-core/commands/hashsum.c (grub_cmd_hashsum): Align space for diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index b0658f01a..3c58d8074 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -84,7 +84,7 @@ struct reassemble grub_uint8_t proto; grub_uint64_t last_time; grub_priority_queue_t pq; - grub_uint8_t *asm_buffer; + struct grub_net_buff *asm_netbuff; grub_size_t total_len; grub_size_t cur_ptr; grub_uint8_t ttl; @@ -351,8 +351,9 @@ free_rsm (struct reassemble *rsm) grub_netbuff_free (*nb); grub_priority_queue_pop (rsm->pq); } - grub_free (rsm->asm_buffer); + grub_netbuff_free (rsm->asm_netbuff); grub_priority_queue_destroy (rsm->pq); + grub_free (rsm); } static void @@ -361,12 +362,16 @@ free_old_fragments (void) struct reassemble *rsm, **prev; grub_uint64_t limit_time = grub_get_time_ms () - 90000; - for (prev = &reassembles, rsm = *prev; rsm; prev = &rsm->next, rsm = *prev) + for (prev = &reassembles, rsm = *prev; rsm; rsm = *prev) if (rsm->last_time < limit_time) { *prev = rsm->next; free_rsm (rsm); } + else + { + prev = &rsm->next; + } } static grub_err_t @@ -473,7 +478,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, grub_free (rsm); return grub_errno; } - rsm->asm_buffer = 0; + rsm->asm_netbuff = 0; rsm->total_len = 0; rsm->cur_ptr = 0; rsm->ttl = 0xff; @@ -492,22 +497,21 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) + (nb->tail - nb->data)); rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t)); - rsm->asm_buffer = grub_zalloc (rsm->total_len); - if (!rsm->asm_buffer) + rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len); + if (!rsm->asm_netbuff) { *prev = rsm->next; free_rsm (rsm); return grub_errno; } } - if (!rsm->asm_buffer) + if (!rsm->asm_netbuff) return GRUB_ERR_NONE; while (1) { struct grub_net_buff **nb_top_p, *nb_top; grub_size_t copy; - grub_uint8_t *res; grub_size_t res_len; struct grub_net_buff *ret; grub_net_ip_protocol_t proto; @@ -532,7 +536,10 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, } if (rsm->cur_ptr < (grub_size_t) 8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)) - return GRUB_ERR_NONE; + { + grub_netbuff_free (nb_top); + return GRUB_ERR_NONE; + } rsm->cur_ptr = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) + (nb_top->tail - nb_top->head)); @@ -547,31 +554,33 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, < copy) copy = rsm->total_len - 8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK); - grub_memcpy (&rsm->asm_buffer[8 * (grub_be_to_cpu16 (iph->frags) - & OFFSET_MASK)], + grub_memcpy (&rsm->asm_netbuff->data[8 * (grub_be_to_cpu16 (iph->frags) + & OFFSET_MASK)], nb_top->data, copy); if ((grub_be_to_cpu16 (iph->frags) & MORE_FRAGMENTS)) - continue; - - res = rsm->asm_buffer; + { + grub_netbuff_free (nb_top); + continue; + } + grub_netbuff_free (nb_top); + + ret = rsm->asm_netbuff; proto = rsm->proto; src = rsm->source; dst = rsm->dest; ttl = rsm->ttl; - rsm->asm_buffer = 0; + rsm->asm_netbuff = 0; res_len = rsm->total_len; *prev = rsm->next; free_rsm (rsm); - ret = grub_malloc (sizeof (*ret)); - if (!ret) + + if (grub_netbuff_put (ret, res_len)) { - grub_free (res); - return grub_errno; + grub_netbuff_free (ret); + return GRUB_ERR_NONE; } - ret->data = ret->head = res; - ret->tail = ret->end = res + res_len; source.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; source.ipv4 = src; diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index f957cb9e5..47b0506ed 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -93,11 +93,12 @@ grub_netbuff_alloc (grub_size_t len) return nb; } -grub_err_t +void grub_netbuff_free (struct grub_net_buff *nb) { + if (!nb) + return; grub_free (nb->head); - return GRUB_ERR_NONE; } grub_err_t diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 1992b8bfe..7cc89390d 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -214,6 +214,7 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), tftph = (struct tftphdr *) nb_top->data; if (grub_be_to_cpu16 (tftph->u.data.block) >= data->block + 1) break; + grub_netbuff_free (nb_top); grub_priority_queue_pop (data->pq); } if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) @@ -248,7 +249,7 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), if ((nb_top->tail - nb_top->data) > 0) grub_net_put_packet (&file->device->net->packs, nb_top); else - grub_netbuff_free (nb); + grub_netbuff_free (nb_top); } } return GRUB_ERR_NONE; @@ -269,7 +270,10 @@ destroy_pq (tftp_data_t data) { struct grub_net_buff **nb_p; while ((nb_p = grub_priority_queue_top (data->pq))) - grub_netbuff_free (*nb_p); + { + grub_netbuff_free (*nb_p); + grub_priority_queue_pop (data->pq); + } grub_priority_queue_destroy (data->pq); } diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h index c745d51d7..9ac168c89 100644 --- a/include/grub/net/netbuff.h +++ b/include/grub/net/netbuff.h @@ -25,6 +25,6 @@ grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff, grub_size_t len); grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff, grub_size_t len); grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); struct grub_net_buff * grub_netbuff_alloc (grub_size_t len); -grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff); +void grub_netbuff_free (struct grub_net_buff *net_buff); #endif