diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c index 749e72dfc..2407e72c5 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -26,6 +26,7 @@ #include grub_err_t (*grub_file_net_seek) (struct grub_file *file, grub_off_t offset) = NULL; +void (*EXPORT_VAR (grub_grubnet_fini)) (void); grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX]; grub_file_filter_t grub_file_filters_enabled[GRUB_FILE_FILTER_MAX]; diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index ad34ea188..3c55096a4 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -264,6 +264,8 @@ grub_machine_init (void) void grub_machine_fini (void) { + if (grub_grubnet_fini) + grub_grubnet_fini (); grub_ofdisk_fini (); grub_console_fini (); } diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 1dbd8a58f..fecde3282 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -39,6 +39,7 @@ grub_net_arp_resolve (struct grub_net_network_level_interface *inf, struct arphdr *arp_header; grub_net_link_level_address_t target_hw_addr; char *aux, arp_data[128]; + grub_err_t err; int i; if (proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 @@ -60,9 +61,12 @@ grub_net_arp_resolve (struct grub_net_network_level_interface *inf, nb.head = arp_data; nb.end = arp_data + sizeof (arp_data); grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb, 128); - grub_netbuff_push (&nb, sizeof (*arp_header) + 2 * (6 + 4)); + + err = grub_netbuff_push (&nb, sizeof (*arp_header) + 2 * (6 + 4)); + if (err) + return err; + arp_header = (struct arphdr *) nb.data; arp_header->hrd = grub_cpu_to_be16 (GRUB_NET_ARPHRD_ETHERNET); arp_header->pro = grub_cpu_to_be16 (GRUB_NET_ETHERTYPE_IP); diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 751583e9d..2c264edb1 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -225,6 +225,13 @@ GRUB_MOD_INIT(ofnet) GRUB_MOD_FINI(ofnet) { + struct grub_net_card *card; + FOR_NET_CARDS (card) + if (card->driver && !grub_strcmp (card->driver->name, "ofnet")) + { + card->driver->fini (card); + card->driver = NULL; + } grub_net_card_driver_unregister (&ofdriver); grub_getbootp = NULL; } diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index f1bc8c1d0..863e659a8 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -15,8 +15,11 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, grub_uint16_t ethertype) { struct etherhdr *eth; + grub_err_t err; - grub_netbuff_push (nb, sizeof (*eth)); + err = grub_netbuff_push (nb, sizeof (*eth)); + if (err) + return err; eth = (struct etherhdr *) nb->data; grub_memcpy (eth->dst, target_addr.mac, 6); grub_memcpy (eth->src, inf->hwaddress.mac, 6); @@ -35,10 +38,13 @@ grub_net_recv_ethernet_packet (struct grub_net_buff * nb, struct snaphdr *snaph; grub_uint16_t type; grub_net_link_level_address_t hwaddress; + grub_err_t err; eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); - grub_netbuff_pull (nb, sizeof (*eth)); + err = grub_netbuff_pull (nb, sizeof (*eth)); + if (err) + return err; if (type <= 1500) { @@ -47,7 +53,9 @@ grub_net_recv_ethernet_packet (struct grub_net_buff * nb, if (llch->dsap == 0xaa && llch->ssap == 0xaa && llch->ctrl == 0x3) { - grub_netbuff_pull (nb, sizeof (*llch)); + err = grub_netbuff_pull (nb, sizeof (*llch)); + if (err) + return err; snaph = (struct snaphdr *) nb->data; type = snaph->type; } diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 808532a4a..776937a6e 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -94,7 +94,9 @@ grub_net_recv_ip_packets (struct grub_net_buff * nb, { struct udphdr *udph; udph = (struct udphdr *) nb->data; - grub_netbuff_pull (nb, sizeof (*udph)); + err = grub_netbuff_pull (nb, sizeof (*udph)); + if (err) + return err; if (grub_be_to_cpu16 (udph->dst) == 68) grub_net_process_dhcp (nb, card); } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 2da60256c..5c7d00991 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -632,6 +632,16 @@ grub_net_open_real (const char *name) return NULL; } +static grub_err_t +grub_net_fs_dir (grub_device_t device, const char *path __attribute__ ((unused)), + int (*hook) (const char *filename, + const struct grub_dirhook_info *info) __attribute__ ((unused))) +{ + if (!device->net) + return grub_error (GRUB_ERR_BAD_FS, "invalid extent"); + return GRUB_ERR_NONE; +} + static grub_err_t grub_net_fs_open (struct grub_file *file, const char *name) { @@ -1224,11 +1234,20 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), return err; } +static void +grub_grubnet_fini_real (void) +{ + struct grub_net_card *card; + + FOR_NET_CARDS (card) + if (card->driver) + card->driver->fini (card); +} static struct grub_fs grub_net_fs = { .name = "netfs", - .dir = NULL, + .dir = grub_net_fs_dir, .open = grub_net_fs_open, .read = grub_net_fs_read, .close = grub_net_fs_close, @@ -1273,6 +1292,7 @@ GRUB_MOD_INIT(net) grub_fs_register (&grub_net_fs); grub_net_open = grub_net_open_real; grub_file_net_seek = grub_net_seek_real; + grub_grubnet_fini = grub_grubnet_fini_real; } GRUB_MOD_FINI(net) @@ -1288,4 +1308,5 @@ GRUB_MOD_FINI(net) grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; grub_file_net_seek = NULL; + grub_grubnet_fini = NULL; } diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index aae2f4d8f..d20104ab0 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -95,12 +95,12 @@ grub_err_t grub_netbuff_free (struct grub_net_buff *nb) { grub_free (nb->head); - return 0; + return GRUB_ERR_NONE; } grub_err_t grub_netbuff_clear (struct grub_net_buff *nb) { nb->data = nb->tail = nb->head; - return 0; + return GRUB_ERR_NONE; } diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 545862092..d0ed7c43a 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -34,7 +34,8 @@ tftp_open (struct grub_file *file, const char *filename) grub_netbuff_clear (&nb); grub_netbuff_reserve (&nb, 1500); - grub_netbuff_push (&nb, sizeof (*tftph)); + if ((err = grub_netbuff_push (&nb, sizeof (*tftph))) != GRUB_ERR_NONE) + return err; tftph = (struct tftphdr *) nb.data; @@ -67,8 +68,8 @@ tftp_open (struct grub_file *file, const char *filename) rrq += grub_strlen ("0") + 1; hdrlen = sizeof (tftph->opcode) + rrqlen; - grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); - + if ((err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen))) != GRUB_ERR_NONE) + return err; file->device->net->socket->out_port = TFTP_SERVER_PORT; err = grub_net_send_udp_packet (file->device->net->socket, &nb); @@ -130,9 +131,9 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) grub_netbuff_clear (nb); break; case TFTP_DATA: - grub_netbuff_pull (nb, sizeof (tftph->opcode) + - sizeof (tftph->u.data.block)); - + if ((err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + + sizeof (tftph->u.data.block))) != GRUB_ERR_NONE) + return err; if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) { data->block++; @@ -141,7 +142,8 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) sock->status = 2; /* Prevent garbage in broken cards. */ if (size > 1024) - grub_netbuff_unput (nb, size - 1024); + if ((err = grub_netbuff_unput (nb, size - 1024)) != GRUB_ERR_NONE) + return err; } else grub_netbuff_clear (nb); @@ -154,8 +156,10 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) } grub_netbuff_clear (&nb_ack); grub_netbuff_reserve (&nb_ack, 128); - grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) - + sizeof (tftph->u.ack.block)); + err = grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) + + sizeof (tftph->u.ack.block)); + if (err) + return err; tftph = (struct tftphdr *) nb_ack.data; tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index cc7534ea1..95134c0cf 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -9,8 +9,11 @@ grub_net_send_udp_packet (const grub_net_socket_t socket, struct grub_net_buff *nb) { struct udphdr *udph; + grub_err_t err; - grub_netbuff_push (nb, sizeof (*udph)); + err = grub_netbuff_push (nb, sizeof (*udph)); + if (err) + return err; udph = (struct udphdr *) nb->data; udph->src = grub_cpu_to_be16 (socket->in_port); diff --git a/include/grub/net.h b/include/grub/net.h index 5d99cace3..068ccec41 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -242,6 +242,7 @@ typedef struct grub_net extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); extern grub_err_t (*EXPORT_VAR (grub_file_net_seek)) (struct grub_file *file, grub_off_t offset); +extern void (*EXPORT_VAR (grub_grubnet_fini)) (void); struct grub_net_network_level_interface {