From a6d37098bd271057743e7e193703c1569ec9f709 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 6 Aug 2019 08:13:33 +0200 Subject: [PATCH] efi_loader: EFI_PXE_BASE_CODE_PROTOCOL stub U-Boot implements the EFI_PXE_BASE_CODE_PROTOCOL because GRUB uses the mode information for booting via PXE. All function pointers in the protocol were NULL up to now which will cause immediate crashes when the services of the protocol are called. Create function stubs for all services of the protocol returning EFI_UNSUPPORTED. Signed-off-by: Heinrich Schuchardt --- include/efi_api.h | 142 +++++++++++++++++++++++++++++++++++---- lib/efi_loader/efi_net.c | 132 +++++++++++++++++++++++++++++++++++- 2 files changed, 257 insertions(+), 17 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index e5634dc6a05..43778197af0 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1287,6 +1287,9 @@ struct efi_simple_network { EFI_GUID(0x03c4e603, 0xac28, 0x11d3, \ 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) +#define EFI_PXE_BASE_CODE_PROTOCOL_REVISION 0x00010000 +#define EFI_PXE_BASE_CODE_MAX_IPCNT 8 + struct efi_pxe_packet { u8 packet[1472]; }; @@ -1321,20 +1324,131 @@ struct efi_pxe_mode { struct efi_pxe_packet pxe_reply; }; -struct efi_pxe { - u64 rev; - void (EFIAPI *start)(void); - void (EFIAPI *stop)(void); - void (EFIAPI *dhcp)(void); - void (EFIAPI *discover)(void); - void (EFIAPI *mftp)(void); - void (EFIAPI *udpwrite)(void); - void (EFIAPI *udpread)(void); - void (EFIAPI *setipfilter)(void); - void (EFIAPI *arp)(void); - void (EFIAPI *setparams)(void); - void (EFIAPI *setstationip)(void); - void (EFIAPI *setpackets)(void); +struct efi_pxe_base_code_srvlist { + u16 type; + u8 accept_any_response; + u8 reserved; + struct efi_ip_address ip_addr; +}; + +struct efi_pxe_base_code_discover_info { + u8 use_m_cast; + u8 use_b_cast; + u8 use_u_cast; + u8 must_use_list; + struct efi_ip_address server_m_cast_ip; + u16 ip_cnt; + struct efi_pxe_base_code_srvlist srv_list[]; +}; + +struct efi_pxe_base_code_mtftp_info { + struct efi_ip_address m_cast_ip; + u16 cport; + u16 sport; + u16 listen_timeout; + u16 transit_timeout; +}; + +struct efi_pxe_base_code_filter { + u8 filters; + u8 ip_cnt; + u16 reserved; + struct efi_ip_address ip_list[EFI_PXE_BASE_CODE_MAX_IPCNT]; +}; + +struct efi_pxe_base_code_dhcpv4_packet { + u8 bootp_op_code; + u8 bootp_hw_type; + u8 bootp_addr_len; + u8 bootp_gate_hops; + u32 bootp_ident; + u16 bootp_seconds; + u16 bootp_flags; + u8 bootp_ci_addr[4]; + u8 bootp_yi_addr[4]; + u8 bootp_si_addr[4]; + u8 bootp_gi_addr[4]; + u8 bootp_hw_addr[16]; + u8 bootp_srv_name[64]; + u8 bootp_boot_file[128]; + u32 dhcp_magick; + u8 dhcp_options[56]; +}; + +struct efi_pxe_base_code_dhcpv6_packet { + u8 message_type; + u8 transaction_id[3]; + u8 dhcp_options[1024]; +}; + +typedef union { + u8 raw[1472]; + struct efi_pxe_base_code_dhcpv4_packet dhcpv4; + struct efi_pxe_base_code_dhcpv6_packet dhcpv6; +} EFI_PXE_BASE_CODE_PACKET; + +struct efi_pxe_base_code_protocol { + u64 revision; + efi_status_t (EFIAPI *start)(struct efi_pxe_base_code_protocol *this, + u8 use_ipv6); + efi_status_t (EFIAPI *stop)(struct efi_pxe_base_code_protocol *this); + efi_status_t (EFIAPI *dhcp)(struct efi_pxe_base_code_protocol *this, + u8 sort_offers); + efi_status_t (EFIAPI *discover)( + struct efi_pxe_base_code_protocol *this, + u16 type, u16 *layer, u8 bis, + struct efi_pxe_base_code_discover_info *info); + efi_status_t (EFIAPI *mtftp)( + struct efi_pxe_base_code_protocol *this, + u32 operation, void *buffer_ptr, + u8 overwrite, efi_uintn_t *buffer_size, + struct efi_ip_address server_ip, char *filename, + struct efi_pxe_base_code_mtftp_info *info, + u8 dont_use_buffer); + efi_status_t (EFIAPI *udp_write)( + struct efi_pxe_base_code_protocol *this, + u16 op_flags, struct efi_ip_address *dest_ip, + u16 *dest_port, + struct efi_ip_address *gateway_ip, + struct efi_ip_address *src_ip, u16 *src_port, + efi_uintn_t *header_size, void *header_ptr, + efi_uintn_t *buffer_size, void *buffer_ptr); + efi_status_t (EFIAPI *udp_read)( + struct efi_pxe_base_code_protocol *this, + u16 op_flags, struct efi_ip_address *dest_ip, + u16 *dest_port, struct efi_ip_address *src_ip, + u16 *src_port, efi_uintn_t *header_size, + void *header_ptr, efi_uintn_t *buffer_size, + void *buffer_ptr); + efi_status_t (EFIAPI *set_ip_filter)( + struct efi_pxe_base_code_protocol *this, + struct efi_pxe_base_code_filter *new_filter); + efi_status_t (EFIAPI *arp)(struct efi_pxe_base_code_protocol *this, + struct efi_ip_address *ip_addr, + struct efi_mac_address *mac_addr); + efi_status_t (EFIAPI *set_parameters)( + struct efi_pxe_base_code_protocol *this, + u8 *new_auto_arp, u8 *new_send_guid, + u8 *new_ttl, u8 *new_tos, + u8 *new_make_callback); + efi_status_t (EFIAPI *set_station_ip)( + struct efi_pxe_base_code_protocol *this, + struct efi_ip_address *new_station_ip, + struct efi_ip_address *new_subnet_mask); + efi_status_t (EFIAPI *set_packets)( + struct efi_pxe_base_code_protocol *this, + u8 *new_dhcp_discover_valid, + u8 *new_dhcp_ack_received, + u8 *new_proxy_offer_received, + u8 *new_pxe_discover_valid, + u8 *new_pxe_reply_received, + u8 *new_pxe_bis_reply_received, + EFI_PXE_BASE_CODE_PACKET *new_dchp_discover, + EFI_PXE_BASE_CODE_PACKET *new_dhcp_acc, + EFI_PXE_BASE_CODE_PACKET *new_proxy_offer, + EFI_PXE_BASE_CODE_PACKET *new_pxe_discover, + EFI_PXE_BASE_CODE_PACKET *new_pxe_reply, + EFI_PXE_BASE_CODE_PACKET *new_pxe_bis_reply); struct efi_pxe_mode *mode; }; diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index d71c6630682..825e064f9aa 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -10,7 +10,8 @@ #include static const efi_guid_t efi_net_guid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; -static const efi_guid_t efi_pxe_guid = EFI_PXE_BASE_CODE_PROTOCOL_GUID; +static const efi_guid_t efi_pxe_base_code_protocol_guid = + EFI_PXE_BASE_CODE_PROTOCOL_GUID; static struct efi_pxe_packet *dhcp_ack; static bool new_rx_packet; static void *new_tx_packet; @@ -39,7 +40,7 @@ struct efi_net_obj { struct efi_object header; struct efi_simple_network net; struct efi_simple_network_mode net_mode; - struct efi_pxe pxe; + struct efi_pxe_base_code_protocol pxe; struct efi_pxe_mode pxe_mode; }; @@ -581,6 +582,118 @@ out: EFI_EXIT(EFI_SUCCESS); } +static efi_status_t EFIAPI efi_pxe_base_code_start( + struct efi_pxe_base_code_protocol *this, + u8 use_ipv6) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_stop( + struct efi_pxe_base_code_protocol *this) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_dhcp( + struct efi_pxe_base_code_protocol *this, + u8 sort_offers) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_discover( + struct efi_pxe_base_code_protocol *this, + u16 type, u16 *layer, u8 bis, + struct efi_pxe_base_code_discover_info *info) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_mtftp( + struct efi_pxe_base_code_protocol *this, + u32 operation, void *buffer_ptr, + u8 overwrite, efi_uintn_t *buffer_size, + struct efi_ip_address server_ip, char *filename, + struct efi_pxe_base_code_mtftp_info *info, + u8 dont_use_buffer) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_udp_write( + struct efi_pxe_base_code_protocol *this, + u16 op_flags, struct efi_ip_address *dest_ip, + u16 *dest_port, + struct efi_ip_address *gateway_ip, + struct efi_ip_address *src_ip, u16 *src_port, + efi_uintn_t *header_size, void *header_ptr, + efi_uintn_t *buffer_size, void *buffer_ptr) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_udp_read( + struct efi_pxe_base_code_protocol *this, + u16 op_flags, struct efi_ip_address *dest_ip, + u16 *dest_port, struct efi_ip_address *src_ip, + u16 *src_port, efi_uintn_t *header_size, + void *header_ptr, efi_uintn_t *buffer_size, + void *buffer_ptr) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_set_ip_filter( + struct efi_pxe_base_code_protocol *this, + struct efi_pxe_base_code_filter *new_filter) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_arp( + struct efi_pxe_base_code_protocol *this, + struct efi_ip_address *ip_addr, + struct efi_mac_address *mac_addr) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_set_parameters( + struct efi_pxe_base_code_protocol *this, + u8 *new_auto_arp, u8 *new_send_guid, + u8 *new_ttl, u8 *new_tos, + u8 *new_make_callback) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_set_station_ip( + struct efi_pxe_base_code_protocol *this, + struct efi_ip_address *new_station_ip, + struct efi_ip_address *new_subnet_mask) +{ + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI efi_pxe_base_code_set_packets( + struct efi_pxe_base_code_protocol *this, + u8 *new_dhcp_discover_valid, + u8 *new_dhcp_ack_received, + u8 *new_proxy_offer_received, + u8 *new_pxe_discover_valid, + u8 *new_pxe_reply_received, + u8 *new_pxe_bis_reply_received, + EFI_PXE_BASE_CODE_PACKET *new_dchp_discover, + EFI_PXE_BASE_CODE_PACKET *new_dhcp_acc, + EFI_PXE_BASE_CODE_PACKET *new_proxy_offer, + EFI_PXE_BASE_CODE_PACKET *new_pxe_discover, + EFI_PXE_BASE_CODE_PACKET *new_pxe_reply, + EFI_PXE_BASE_CODE_PACKET *new_pxe_bis_reply) +{ + return EFI_UNSUPPORTED; +} + /** * efi_net_register() - register the simple network protocol * @@ -619,7 +732,7 @@ efi_status_t efi_net_register(void) efi_dp_from_eth()); if (r != EFI_SUCCESS) goto failure_to_add_protocol; - r = efi_add_protocol(&netobj->header, &efi_pxe_guid, + r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid, &netobj->pxe); if (r != EFI_SUCCESS) goto failure_to_add_protocol; @@ -644,6 +757,19 @@ efi_status_t efi_net_register(void) netobj->net_mode.max_packet_size = PKTSIZE; netobj->net_mode.if_type = ARP_ETHER; + netobj->pxe.revision = EFI_PXE_BASE_CODE_PROTOCOL_REVISION; + netobj->pxe.start = efi_pxe_base_code_start; + netobj->pxe.stop = efi_pxe_base_code_stop; + netobj->pxe.dhcp = efi_pxe_base_code_dhcp; + netobj->pxe.discover = efi_pxe_base_code_discover; + netobj->pxe.mtftp = efi_pxe_base_code_mtftp; + netobj->pxe.udp_write = efi_pxe_base_code_udp_write; + netobj->pxe.udp_read = efi_pxe_base_code_udp_read; + netobj->pxe.set_ip_filter = efi_pxe_base_code_set_ip_filter; + netobj->pxe.arp = efi_pxe_base_code_arp; + netobj->pxe.set_parameters = efi_pxe_base_code_set_parameters; + netobj->pxe.set_station_ip = efi_pxe_base_code_set_station_ip; + netobj->pxe.set_packets = efi_pxe_base_code_set_packets; netobj->pxe.mode = &netobj->pxe_mode; if (dhcp_ack) netobj->pxe_mode.dhcp_ack = *dhcp_ack; -- 2.39.2