diff options
author | CoprDistGit <infra@openeuler.org> | 2025-09-26 09:37:13 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2025-09-26 09:37:13 +0000 |
commit | cd89936adc4a4edf7159d1b5b52db7f4d259f969 (patch) | |
tree | 1860f1803a453929df1f57d935ed5ecd0735c0fc | |
parent | 9ab1f398ff46cfc4a8be3fa18c8e5565124a958a (diff) |
automatic import of ipxe
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | 0001-build-customize-configuration.patch | 6 | ||||
-rw-r--r-- | 0002-Use-spec-compliant-timeouts.patch | 98 | ||||
-rw-r--r-- | 0003-librm-Use-explicit-operand-size-when-pushing-a-label.patch | 62 | ||||
-rw-r--r-- | backport-allow-for-relative-uris-that-include-colons-within-the-path.patch | 90 | ||||
-rw-r--r-- | backport-avoid-infinite-loop-on-allocation-failure-in.patch | 69 | ||||
-rw-r--r-- | backport-do-not-clear-current-working-url-when-executing-embedded-image.patch | 56 | ||||
-rw-r--r-- | backport-ensure-that-pci_read_config-initialises-all-fields.patch | 45 | ||||
-rw-r--r-- | backport-retain-original-encodings-for-path-query-and-fragment-fields.patch | 629 | ||||
-rw-r--r-- | ipxe.spec | 259 | ||||
-rw-r--r-- | sources | 1 |
11 files changed, 1316 insertions, 0 deletions
@@ -0,0 +1 @@ +/v1.21.1.tar.gz diff --git a/0001-build-customize-configuration.patch b/0001-build-customize-configuration.patch new file mode 100644 index 0000000..045561a --- /dev/null +++ b/0001-build-customize-configuration.patch @@ -0,0 +1,6 @@ +diff -rupN ipxe-20190125-git36a4c85f/src/config/local/general.h ipxe-20190125-git36a4c85f.new/src/config/local/general.h +--- ipxe-20190125-git36a4c85f/src/config/local/general.h 1970-01-01 01:00:00.000000000 +0100 ++++ ipxe-20190125-git36a4c85f.new/src/config/local/general.h 2019-02-01 16:40:42.725293033 +0000 +@@ -0,0 +1,2 @@ ++/* Enable IPv6. */ ++#define NET_PROTO_IPV6 diff --git a/0002-Use-spec-compliant-timeouts.patch b/0002-Use-spec-compliant-timeouts.patch new file mode 100644 index 0000000..f1a4d50 --- /dev/null +++ b/0002-Use-spec-compliant-timeouts.patch @@ -0,0 +1,98 @@ +From bc252caa54fcfb2e9fd0ddb01ebaa50192e85c38 Mon Sep 17 00:00:00 2001 +From: Alex Williamson <alex.williamson@redhat.com> +Date: Wed, 21 Oct 2015 11:18:40 +0200 +Subject: Use spec compliant timeouts + +Message-id: <20150428212403.31299.29391.stgit@gimli.home> +Patchwork-id: 64951 +O-Subject: [RHEL7.2 ipxe PATCH 2/2] [dhcp][RHEL-only] Use spec compliant timeouts +Bugzilla: 1196352 +RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> +RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com> +RH-Acked-by: Laszlo Ersek <lersek@redhat.com> + +Use local config to override iPXE's abbreviated DHCP timeouts using +the recommended values for spec compliance. This matches the state +of RHEL6 gPXE DHCP timeouts after bz968474 + bz1206042 + +Signed-off-by: Alex Williamson <alex.williamson@redhat.com> +Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> +(cherry picked from commit 7038f41c0131d263de5165b416500009acdbf550) +--- + src/config/local/.gitignore | 1 - + src/config/local/dhcp.h | 62 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 62 insertions(+), 1 deletion(-) + delete mode 100644 src/config/local/.gitignore + create mode 100644 src/config/local/dhcp.h + +diff --git a/src/config/local/dhcp.h b/src/config/local/dhcp.h +new file mode 100644 +index 0000000..83df5b8 +--- /dev/null ++++ b/src/config/local/dhcp.h +@@ -0,0 +1,62 @@ ++/* ++ * Downstream localization ++ * ++ * For RHEL, use spec compliant DHCP timeouts (bz1196352) ++ */ ++ ++/* ++ * PXE spec defines timeouts of 4, 8, 16, 32 seconds ++ */ ++#undef DHCP_DISC_START_TIMEOUT_SEC ++#define DHCP_DISC_START_TIMEOUT_SEC 4 ++#undef DHCP_DISC_END_TIMEOUT_SEC ++#define DHCP_DISC_END_TIMEOUT_SEC 32 ++ ++/* ++ * Elapsed time used for early break waiting for ProxyDHCP, this therefore ++ * needs to be less than the cumulative time for the first 2 timeouts. ++ */ ++#undef DHCP_DISC_PROXY_TIMEOUT_SEC ++#define DHCP_DISC_PROXY_TIMEOUT_SEC 11 ++ ++/* ++ * Approximate PXE spec requirement using minimum timeout (0.25s) for ++ * timeouts of 0.25, 0.5, 1, 2, 4 ++ */ ++#undef DHCP_REQ_START_TIMEOUT_SEC ++#define DHCP_REQ_START_TIMEOUT_SEC 0 ++#undef DHCP_REQ_END_TIMEOUT_SEC ++#define DHCP_REQ_END_TIMEOUT_SEC 4 ++ ++/* ++ * Same as normal request phase, except non-fatal, so we extend the timer ++ * to 8 and set the early timeout to an elapsed time value that causes a ++ * break after the 4 second timeout. At least that's what we'd like to do, ++ * but our timer operates at 18Hz and has a minimum resolution of 7 cycles. ++ * Therefore the above quarter-second starting timeout looks more like ++ * 0.39s, 0.78s, 1.56s, 3.11s, 6.22s. If we had an ideal timer, we could ++ * set the timeout to 7s (0.25 + 0.5 + 1 + 2 + 4 = 7.75s) and exit without ++ * failure when the timer rolls over to 8s. With our timer, we get 0.39 + ++ * 0.78 + 1.56 + 3.11 = 5.84s. The next timeout would take us to 12.06s ++ * (+6.22). That seems like a long time to wait for an optional reply, so ++ * we reduce the early timeout to 5s to exit before the timer exceeds the ++ * max and causes a failure. This still adds one extra cycle vs the ++ * upstream defaults. ++ */ ++#undef DHCP_PROXY_START_TIMEOUT_SEC ++#define DHCP_PROXY_START_TIMEOUT_SEC 0 ++#undef DHCP_PROXY_END_TIMEOUT_SEC ++#define DHCP_PROXY_END_TIMEOUT_SEC 8 ++#undef DHCP_REQ_PROXY_TIMEOUT_SEC ++#define DHCP_REQ_PROXY_TIMEOUT_SEC 5 ++ ++/* ++ * Same as above, retry each server using our approximation of standard ++ * timeouts and exit before timer induced failure. ++ */ ++#undef PXEBS_START_TIMEOUT_SEC ++#define PXEBS_START_TIMEOUT_SEC 0 ++#undef PXEBS_END_TIMEOUT_SEC ++#define PXEBS_END_TIMEOUT_SEC 8 ++#undef PXEBS_MAX_TIMEOUT_SEC ++#define PXEBS_MAX_TIMEOUT_SEC 5 +-- +1.8.3.1 + diff --git a/0003-librm-Use-explicit-operand-size-when-pushing-a-label.patch b/0003-librm-Use-explicit-operand-size-when-pushing-a-label.patch new file mode 100644 index 0000000..6aa5107 --- /dev/null +++ b/0003-librm-Use-explicit-operand-size-when-pushing-a-label.patch @@ -0,0 +1,62 @@ +From 0aa2e4ec963597794dd8f8b36f77f4d0cf4e03c8 Mon Sep 17 00:00:00 2001 +From: Michael Brown <mcb30@ipxe.org> +Date: Tue, 5 Sep 2023 19:47:38 +0800 +Subject: [PATCH] [librm] Use explicit operand size when pushing a label + address + +We currently use "push $1f" within inline assembly to push the address +of the real-mode code fragment, relying on the assembler to treat this +as "pushl" for 32-bit code or "pushq" for 64-bit code. + +As of binutils commit 5cc0077 ("x86: further adjust extend-to-32bit- +address conditions"), first included in binutils-2.41, this implicit +operand size is no longer calculated as expected and 64-bit builds +will fail with + + Error: operand size mismatch for `push' + +Fix by adding an explicit operand size to the "push" instruction. + +Originally-fixed-by: Justin Cano <jstncno@gmail.com> +Signed-off-by: Michael Brown <mcb30@ipxe.org> + +--- + src/arch/x86/include/librm.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/arch/x86/include/librm.h b/src/arch/x86/include/librm.h +index 5196d39..40f0754 100644 +--- a/src/arch/x86/include/librm.h ++++ b/src/arch/x86/include/librm.h +@@ -250,8 +250,10 @@ extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); + /* CODE_DEFAULT: restore default .code32/.code64 directive */ + #ifdef __x86_64__ + #define CODE_DEFAULT ".code64" ++#define STACK_DEFAULT "q" + #else + #define CODE_DEFAULT ".code32" ++#define STACK_DEFAULT "l" + #endif + + /* LINE_SYMBOL: declare a symbol for the current source code line */ +@@ -268,7 +270,7 @@ extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); + + /* REAL_CODE: declare a fragment of code that executes in real mode */ + #define REAL_CODE( asm_code_str ) \ +- "push $1f\n\t" \ ++ "push" STACK_DEFAULT " $1f\n\t" \ + "call real_call\n\t" \ + TEXT16_CODE ( "\n1:\n\t" \ + asm_code_str \ +@@ -277,7 +279,7 @@ extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); + + /* PHYS_CODE: declare a fragment of code that executes in flat physical mode */ + #define PHYS_CODE( asm_code_str ) \ +- "push $1f\n\t" \ ++ "push" STACK_DEFAULT " $1f\n\t" \ + "call phys_call\n\t" \ + ".section \".text.phys\", \"ax\", @progbits\n\t"\ + "\n" LINE_SYMBOL "\n\t" \ +-- +2.44.0 + diff --git a/backport-allow-for-relative-uris-that-include-colons-within-the-path.patch b/backport-allow-for-relative-uris-that-include-colons-within-the-path.patch new file mode 100644 index 0000000..4bb1747 --- /dev/null +++ b/backport-allow-for-relative-uris-that-include-colons-within-the-path.patch @@ -0,0 +1,90 @@ +From e814d33900992e034a8c3ddec2c65463c5206090 Mon Sep 17 00:00:00 2001 +From: Michael Brown <mcb30@ipxe.org> +Date: Thu, 13 Jan 2022 14:53:36 +0000 +Subject: [PATCH] [uri] Allow for relative URIs that include colons within the + path + +RFC3986 allows for colons to appear within the path component of a +relative URI, but iPXE will currently parse such URIs incorrectly by +interpreting the text before the colon as the URI scheme. + +Fix by checking for valid characters when identifying the URI scheme. +Deliberately deviate from the RFC3986 definition of valid characters +by accepting "_" (which was incorrectly used in the iPXE-specific +"ib_srp" URI scheme and so must be accepted for compatibility with +existing deployments), and by omitting the code to check for +characters that are not used in any URI scheme supported by iPXE. + +Reported-by: Ignat Korchagin <ignat@cloudflare.com> +Signed-off-by: Michael Brown <mcb30@ipxe.org> + +Conflict:NA +Reference:https://github.com/ipxe/ipxe/commit/e814d33900992e034a8c3ddec2c65463c5206090 +--- + src/core/uri.c | 15 ++++++++++----- + src/tests/uri_test.c | 10 ++++++++++ + 2 files changed, 20 insertions(+), 5 deletions(-) + +diff --git a/src/core/uri.c b/src/core/uri.c +index a0f79e9ec1..b82472ef03 100644 +--- a/src/core/uri.c ++++ b/src/core/uri.c +@@ -334,8 +334,15 @@ struct uri * parse_uri ( const char *uri_string ) { + uri->efragment = tmp; + } + +- /* Identify absolute/relative URI */ +- if ( ( tmp = strchr ( raw, ':' ) ) ) { ++ /* Identify absolute URIs */ ++ epath = raw; ++ for ( tmp = raw ; ; tmp++ ) { ++ /* Possible scheme character (for our URI schemes) */ ++ if ( isalpha ( *tmp ) || ( *tmp == '-' ) || ( *tmp == '_' ) ) ++ continue; ++ /* Invalid scheme character or NUL: is a relative URI */ ++ if ( *tmp != ':' ) ++ break; + /* Absolute URI: identify hierarchical/opaque */ + uri->scheme = raw; + *(tmp++) = '\0'; +@@ -347,9 +354,7 @@ struct uri * parse_uri ( const char *uri_string ) { + uri->opaque = tmp; + epath = NULL; + } +- } else { +- /* Relative URI */ +- epath = raw; ++ break; + } + + /* If we don't have a path (i.e. we have an absolute URI with +diff --git a/src/tests/uri_test.c b/src/tests/uri_test.c +index 929ab36325..338f479cd3 100644 +--- a/src/tests/uri_test.c ++++ b/src/tests/uri_test.c +@@ -657,6 +657,15 @@ static struct uri_test uri_file_volume = { + }, + }; + ++/** Relative URI with colons in path */ ++static struct uri_test uri_colons = { ++ "/boot/52:54:00:12:34:56/boot.ipxe", ++ { ++ .path = "/boot/52:54:00:12:34:56/boot.ipxe", ++ .epath = "/boot/52:54:00:12:34:56/boot.ipxe", ++ }, ++}; ++ + /** URI with port number */ + static struct uri_port_test uri_explicit_port = { + "http://192.168.0.1:8080/boot.php", +@@ -957,6 +966,7 @@ static void uri_test_exec ( void ) { + uri_parse_format_dup_ok ( &uri_file_relative ); + uri_parse_format_dup_ok ( &uri_file_absolute ); + uri_parse_format_dup_ok ( &uri_file_volume ); ++ uri_parse_format_dup_ok ( &uri_colons ); + + /** URI port number tests */ + uri_port_ok ( &uri_explicit_port ); + + diff --git a/backport-avoid-infinite-loop-on-allocation-failure-in.patch b/backport-avoid-infinite-loop-on-allocation-failure-in.patch new file mode 100644 index 0000000..8dffce5 --- /dev/null +++ b/backport-avoid-infinite-loop-on-allocation-failure-in.patch @@ -0,0 +1,69 @@ +From 614d99eba149d0fafc64dfdddc7ef04970e0d86c Mon Sep 17 00:00:00 2001 +From: Michael Brown <mcb30@ipxe.org> +Date: Tue, 20 Apr 2021 13:28:57 +0100 +Subject: [PATCH] [xen] Avoid infinite loop on allocation failure in + xenstore_response() +Signed-off-by: Michael Brown <mcb30@ipxe.org> +Conflict:NA +Reference:https://github.com/ipxe/ipxe/commit/614d99eba149d0fafc64dfdddc7ef04970e0d86c +--- + src/interface/xen/xenstore.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) +diff --git a/src/interface/xen/xenstore.c b/src/interface/xen/xenstore.c +index a14881f..c2da532 100644 +--- a/src/interface/xen/xenstore.c ++++ b/src/interface/xen/xenstore.c +@@ -68,14 +68,14 @@ static void xenstore_send ( struct xen_hypervisor *xen, const void *data, + XENSTORE_RING_IDX cons; + XENSTORE_RING_IDX idx; + const char *bytes = data; +- size_t offset = 0; ++ size_t offset; + size_t fill; + + DBGCP ( intf, "XENSTORE raw request:\n" ); + DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( prod ), data, len ); + + /* Write one byte at a time */ +- while ( offset < len ) { ++ for ( offset =0 ; offset < len ; offset++ ) { + + /* Wait for space to become available */ + while ( 1 ) { +@@ -90,7 +90,7 @@ static void xenstore_send ( struct xen_hypervisor *xen, const void *data, + + /* Write byte */ + idx = MASK_XENSTORE_IDX ( prod++ ); +- writeb ( bytes[offset++], &intf->req[idx] ); ++ writeb ( bytes[offset], &intf->req[idx] ); + } + + /* Update producer counter */ +@@ -125,13 +125,13 @@ static void xenstore_recv ( struct xen_hypervisor *xen, void *data, + XENSTORE_RING_IDX prod; + XENSTORE_RING_IDX idx; + char *bytes = data; +- size_t offset = 0; ++ size_t offset; + size_t fill; + + DBGCP ( intf, "XENSTORE raw response:\n" ); + + /* Read one byte at a time */ +- while ( offset < len ) { ++ for ( offset = 0 ; offset < len ; offset++ ) { + + /* Wait for data to be ready */ + while ( 1 ) { +@@ -147,7 +147,7 @@ static void xenstore_recv ( struct xen_hypervisor *xen, void *data, + /* Read byte */ + idx = MASK_XENSTORE_IDX ( cons++ ); + if ( data ) +- bytes[offset++] = readb ( &intf->rsp[idx] ); ++ bytes[offset] = readb ( &intf->rsp[idx] ); + } + if ( data ) + DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( cons - len ), data, len ); +-- +2.23.0 + diff --git a/backport-do-not-clear-current-working-url-when-executing-embedded-image.patch b/backport-do-not-clear-current-working-url-when-executing-embedded-image.patch new file mode 100644 index 0000000..06b8081 --- /dev/null +++ b/backport-do-not-clear-current-working-url-when-executing-embedded-image.patch @@ -0,0 +1,56 @@ +From 5d22307c4161dde453d50e8dc7bef8b3a2f6c9b3 Mon Sep 17 00:00:00 2001 +From: Michael Brown <mcb30@ipxe.org> +Date: Tue, 15 Feb 2022 14:28:01 +0000 +Subject: [PATCH] [image] Do not clear current working URI when executing + embedded image + +Embedded images do not have an associated URI. This currently causes +the current working URI (cwuri) to be cleared when starting an +embedded image. + +If the current working URI has been set via a ${next-server} setting +from a cached DHCP packet then this will result in unexpected +behaviour. An attempt by the embedded script to use a relative URI to +download files from the TFTP server will fail with the error: + + Could not start download: Operation not supported (ipxe.org/3c092083) + +Rerunning the "dhcp" command will not fix this error, since the TFTP +settings applicator will not see any change to the ${next-server} +setting and so will not reset the current working URI. + +Fix by setting the current working URI to the image's URI only if the +image actually has an associated URI. + +Debugged-by: Ignat Korchagin <ignat@cloudflare.com> +Originally-fixed-by: Ignat Korchagin <ignat@cloudflare.com> +Tested-by: Ignat Korchagin <ignat@cloudflare.com> +Signed-off-by: Michael Brown <mcb30@ipxe.org> + +Conflict:NA +Reference:https://github.com/ipxe/ipxe/commit/5d22307c4161dde453d50e8dc7bef8b3a2f6c9b3 +--- + src/core/image.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/core/image.c b/src/core/image.c +index ce8cf868b0..3e236ca603 100644 +--- a/src/core/image.c ++++ b/src/core/image.c +@@ -338,9 +338,12 @@ int image_exec ( struct image *image ) { + /* Sanity check */ + assert ( image->flags & IMAGE_REGISTERED ); + +- /* Switch current working directory to be that of the image itself */ ++ /* Switch current working directory to be that of the image ++ * itself, if applicable ++ */ + old_cwuri = uri_get ( cwuri ); +- churi ( image->uri ); ++ if ( image->uri ) ++ churi ( image->uri ); + + /* Preserve record of any currently-running image */ + saved_current_image = current_image; + + diff --git a/backport-ensure-that-pci_read_config-initialises-all-fields.patch b/backport-ensure-that-pci_read_config-initialises-all-fields.patch new file mode 100644 index 0000000..a03b950 --- /dev/null +++ b/backport-ensure-that-pci_read_config-initialises-all-fields.patch @@ -0,0 +1,45 @@ +From 04288974f6d81019314cbf9cbd72ab1fae95496f Mon Sep 17 00:00:00 2001 +From: Michael Brown <mcb30@ipxe.org> +Date: Wed, 16 Feb 2022 12:30:02 +0000 +Subject: [PATCH] [pci] Ensure that pci_read_config() initialises all fields + +As per the general pattern for initialisation functions in iPXE, +pci_init() saves code size by assuming that the caller has already +zeroed the underlying storage (e.g. as part of zeroing a larger +containing structure). There are several places within the code where +pci_init() is deliberately used to initialise a transient struct +pci_device without zeroing the entire structure, because the calling +code knows that only the PCI bus:dev.fn address is required to be +initialised (e.g. when reading from PCI configuration space). + +Ensure that using pci_init() followed by pci_read_config() will fully +initialise the struct pci_device even if the caller did not previously +zero the underlying storage, since Coverity reports that there are +several places in the code that rely upon this. + +Signed-off-by: Michael Brown <mcb30@ipxe.org> + +Conflict:NA +Reference:https://github.com/ipxe/ipxe/commit/04288974f6d81019314cbf9cbd72ab1fae95496f +--- + src/drivers/bus/pci.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c +index 1b7350c8b8..5891e42ff4 100644 +--- a/src/drivers/bus/pci.c ++++ b/src/drivers/bus/pci.c +@@ -121,6 +121,11 @@ static void pci_read_bases ( struct pci_device *pci ) { + unsigned long bar; + int reg; + ++ /* Clear any existing base addresses */ ++ pci->ioaddr = 0; ++ pci->membase = 0; ++ ++ /* Get first memory and I/O BAR addresses */ + for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) { + bar = pci_bar ( pci, reg ); + if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) { + + diff --git a/backport-retain-original-encodings-for-path-query-and-fragment-fields.patch b/backport-retain-original-encodings-for-path-query-and-fragment-fields.patch new file mode 100644 index 0000000..0ba9b05 --- /dev/null +++ b/backport-retain-original-encodings-for-path-query-and-fragment-fields.patch @@ -0,0 +1,629 @@ +From 1844aacc837bf81cb1959fa65f2e52dcc70a0cae Mon Sep 17 00:00:00 2001 +From: Michael Brown <mcb30@ipxe.org> +Date: Thu, 11 Nov 2021 23:31:23 +0000 +Subject: [PATCH] [uri] Retain original encodings for path, query, and fragment + fields + +iPXE decodes any percent-encoded characters during the URI parsing +stage, thereby allowing protocol implementations to consume the raw +field values directly without further decoding. + +When reconstructing a URI string for use in an HTTP request line, the +percent-encoding is currently reapplied in a reversible way: we +guarantee that our reconstructed URI string could be decoded to give +the same raw field values. + +This technically violates RFC3986, which states that "URIs that differ +in the replacement of a reserved character with its corresponding +percent-encoded octet are not equivalent". Experiments show that +several HTTP server applications will attach meaning to the choice of +whether or not a particular character was percent-encoded, even when +the percent-encoding is unnecessary from the perspective of parsing +the URI into its component fields. + +Fix by storing the originally encoded substrings for the path, query, +and fragment fields and using these original encoded versions when +reconstructing a URI string. The path field is also stored as a +decoded string, for use by protocols such as TFTP that communicate +using raw strings rather than URI-encoded strings. All other fields +(such as the username and password) continue to be stored only in +their decoded versions since nothing ever needs to know the originally +encoded versions of these fields. + +Signed-off-by: Michael Brown <mcb30@ipxe.org> + +Conflict:NA +Reference:https://github.com/ipxe/ipxe/commit/1844aacc837bf81cb1959fa65f2e52dcc70a0cae +--- + src/core/uri.c | 131 +++++++++++++++++++++++++---------------- + src/include/ipxe/uri.h | 31 +++++++--- + src/net/tcp/httpcore.c | 4 +- + src/tests/uri_test.c | 53 +++++++++++++---- + src/usr/imgmgmt.c | 4 +- + 5 files changed, 148 insertions(+), 75 deletions(-) + +diff --git a/src/core/uri.c b/src/core/uri.c +index e9e512ab4a..a0f79e9ec1 100644 +--- a/src/core/uri.c ++++ b/src/core/uri.c +@@ -79,12 +79,10 @@ size_t uri_decode ( const char *encoded, void *buf, size_t len ) { + /** + * Decode URI field in-place + * +- * @v uri URI +- * @v field URI field index ++ * @v encoded Encoded field, or NULL + */ +-static void uri_decode_inplace ( struct uri *uri, unsigned int field ) { +- const char *encoded = uri_field ( uri, field ); +- char *decoded = ( ( char * ) encoded ); ++static void uri_decode_inplace ( char *encoded ) { ++ char *decoded = encoded; + size_t len; + + /* Do nothing if field is not present */ +@@ -150,7 +148,7 @@ static int uri_character_escaped ( char c, unsigned int field ) { + * parser but for any other URI parsers (e.g. HTTP query + * string parsers, which care about '=' and '&'). + */ +- static const char *escaped[URI_FIELDS] = { ++ static const char *escaped[URI_EPATH] = { + /* Scheme or default: escape everything */ + [URI_SCHEME] = "/#:@?=&", + /* Opaque part: escape characters which would affect +@@ -172,20 +170,21 @@ static int uri_character_escaped ( char c, unsigned int field ) { + * appears within paths. + */ + [URI_PATH] = "#:@?", +- /* Query: escape everything except '/', which +- * sometimes appears within queries. +- */ +- [URI_QUERY] = "#:@?", +- /* Fragment: escape everything */ +- [URI_FRAGMENT] = "/#:@?", + }; + +- return ( /* Always escape non-printing characters and whitespace */ +- ( ! isprint ( c ) ) || ( c == ' ' ) || +- /* Always escape '%' */ +- ( c == '%' ) || +- /* Escape field-specific characters */ +- strchr ( escaped[field], c ) ); ++ /* Always escape non-printing characters and whitespace */ ++ if ( ( ! isprint ( c ) ) || ( c == ' ' ) ) ++ return 1; ++ ++ /* Escape nothing else in already-escaped fields */ ++ if ( field >= URI_EPATH ) ++ return 0; ++ ++ /* Escape '%' and any field-specific characters */ ++ if ( ( c == '%' ) || strchr ( escaped[field], c ) ) ++ return 1; ++ ++ return 0; + } + + /** +@@ -262,10 +261,12 @@ static void uri_dump ( const struct uri *uri ) { + DBGC ( uri, " port \"%s\"", uri->port ); + if ( uri->path ) + DBGC ( uri, " path \"%s\"", uri->path ); +- if ( uri->query ) +- DBGC ( uri, " query \"%s\"", uri->query ); +- if ( uri->fragment ) +- DBGC ( uri, " fragment \"%s\"", uri->fragment ); ++ if ( uri->epath ) ++ DBGC ( uri, " epath \"%s\"", uri->epath ); ++ if ( uri->equery ) ++ DBGC ( uri, " equery \"%s\"", uri->equery ); ++ if ( uri->efragment ) ++ DBGC ( uri, " efragment \"%s\"", uri->efragment ); + if ( uri->params ) + DBGC ( uri, " params \"%s\"", uri->params->name ); + } +@@ -298,17 +299,19 @@ struct uri * parse_uri ( const char *uri_string ) { + char *raw; + char *tmp; + char *path; ++ char *epath; + char *authority; + size_t raw_len; + unsigned int field; + +- /* Allocate space for URI struct and a copy of the string */ ++ /* Allocate space for URI struct and two copies of the string */ + raw_len = ( strlen ( uri_string ) + 1 /* NUL */ ); +- uri = zalloc ( sizeof ( *uri ) + raw_len ); ++ uri = zalloc ( sizeof ( *uri ) + ( 2 * raw_len ) ); + if ( ! uri ) + return NULL; + ref_init ( &uri->refcnt, uri_free ); + raw = ( ( ( void * ) uri ) + sizeof ( *uri ) ); ++ path = ( raw + raw_len ); + + /* Copy in the raw string */ + memcpy ( raw, uri_string, raw_len ); +@@ -328,7 +331,7 @@ struct uri * parse_uri ( const char *uri_string ) { + /* Chop off the fragment, if it exists */ + if ( ( tmp = strchr ( raw, '#' ) ) ) { + *(tmp++) = '\0'; +- uri->fragment = tmp; ++ uri->efragment = tmp; + } + + /* Identify absolute/relative URI */ +@@ -338,47 +341,47 @@ struct uri * parse_uri ( const char *uri_string ) { + *(tmp++) = '\0'; + if ( *tmp == '/' ) { + /* Absolute URI with hierarchical part */ +- path = tmp; ++ epath = tmp; + } else { + /* Absolute URI with opaque part */ + uri->opaque = tmp; +- path = NULL; ++ epath = NULL; + } + } else { + /* Relative URI */ +- path = raw; ++ epath = raw; + } + + /* If we don't have a path (i.e. we have an absolute URI with + * an opaque portion, we're already finished processing + */ +- if ( ! path ) ++ if ( ! epath ) + goto done; + + /* Chop off the query, if it exists */ +- if ( ( tmp = strchr ( path, '?' ) ) ) { ++ if ( ( tmp = strchr ( epath, '?' ) ) ) { + *(tmp++) = '\0'; +- uri->query = tmp; ++ uri->equery = tmp; + } + + /* If we have no path remaining, then we're already finished + * processing. + */ +- if ( ! path[0] ) ++ if ( ! epath[0] ) + goto done; + + /* Identify net/absolute/relative path */ +- if ( uri->scheme && ( strncmp ( path, "//", 2 ) == 0 ) ) { ++ if ( uri->scheme && ( strncmp ( epath, "//", 2 ) == 0 ) ) { + /* Net path. If this is terminated by the first '/' + * of an absolute path, then we have no space for a + * terminator after the authority field, so shuffle + * the authority down by one byte, overwriting one of + * the two slashes. + */ +- authority = ( path + 2 ); ++ authority = ( epath + 2 ); + if ( ( tmp = strchr ( authority, '/' ) ) ) { + /* Shuffle down */ +- uri->path = tmp; ++ uri->epath = tmp; + memmove ( ( authority - 1 ), authority, + ( tmp - authority ) ); + authority--; +@@ -386,10 +389,16 @@ struct uri * parse_uri ( const char *uri_string ) { + } + } else { + /* Absolute/relative path */ +- uri->path = path; ++ uri->epath = epath; + authority = NULL; + } + ++ /* Create copy of path for decoding */ ++ if ( uri->epath ) { ++ strcpy ( path, uri->epath ); ++ uri->path = path; ++ } ++ + /* If we don't have an authority (i.e. we have a non-net + * path), we're already finished processing + */ +@@ -421,8 +430,8 @@ struct uri * parse_uri ( const char *uri_string ) { + + done: + /* Decode fields in-place */ +- for ( field = 0 ; field < URI_FIELDS ; field++ ) +- uri_decode_inplace ( uri, field ); ++ for ( field = 0 ; field < URI_EPATH ; field++ ) ++ uri_decode_inplace ( ( char * ) uri_field ( uri, field ) ); + + DBGC ( uri, "URI parsed \"%s\" to", uri_string ); + uri_dump ( uri ); +@@ -458,8 +467,8 @@ size_t format_uri ( const struct uri *uri, char *buf, size_t len ) { + static const char prefixes[URI_FIELDS] = { + [URI_PASSWORD] = ':', + [URI_PORT] = ':', +- [URI_QUERY] = '?', +- [URI_FRAGMENT] = '#', ++ [URI_EQUERY] = '?', ++ [URI_EFRAGMENT] = '#', + }; + char prefix; + size_t used = 0; +@@ -480,6 +489,10 @@ size_t format_uri ( const struct uri *uri, char *buf, size_t len ) { + if ( ! uri_field ( uri, field ) ) + continue; + ++ /* Skip path field if encoded path is present */ ++ if ( ( field == URI_PATH ) && uri->epath ) ++ continue; ++ + /* Prefix this field, if applicable */ + prefix = prefixes[field]; + if ( ( field == URI_HOST ) && ( uri->user != NULL ) ) +@@ -676,6 +689,7 @@ char * resolve_path ( const char *base_path, + struct uri * resolve_uri ( const struct uri *base_uri, + struct uri *relative_uri ) { + struct uri tmp_uri; ++ char *tmp_epath = NULL; + char *tmp_path = NULL; + struct uri *new_uri; + +@@ -685,20 +699,27 @@ struct uri * resolve_uri ( const struct uri *base_uri, + + /* Mangle URI */ + memcpy ( &tmp_uri, base_uri, sizeof ( tmp_uri ) ); +- if ( relative_uri->path ) { +- tmp_path = resolve_path ( ( base_uri->path ? +- base_uri->path : "/" ), +- relative_uri->path ); ++ if ( relative_uri->epath ) { ++ tmp_epath = resolve_path ( ( base_uri->epath ? ++ base_uri->epath : "/" ), ++ relative_uri->epath ); ++ if ( ! tmp_epath ) ++ goto err_epath; ++ tmp_path = strdup ( tmp_epath ); ++ if ( ! tmp_path ) ++ goto err_path; ++ uri_decode_inplace ( tmp_path ); ++ tmp_uri.epath = tmp_epath; + tmp_uri.path = tmp_path; +- tmp_uri.query = relative_uri->query; +- tmp_uri.fragment = relative_uri->fragment; ++ tmp_uri.equery = relative_uri->equery; ++ tmp_uri.efragment = relative_uri->efragment; + tmp_uri.params = relative_uri->params; +- } else if ( relative_uri->query ) { +- tmp_uri.query = relative_uri->query; +- tmp_uri.fragment = relative_uri->fragment; ++ } else if ( relative_uri->equery ) { ++ tmp_uri.equery = relative_uri->equery; ++ tmp_uri.efragment = relative_uri->efragment; + tmp_uri.params = relative_uri->params; +- } else if ( relative_uri->fragment ) { +- tmp_uri.fragment = relative_uri->fragment; ++ } else if ( relative_uri->efragment ) { ++ tmp_uri.efragment = relative_uri->efragment; + tmp_uri.params = relative_uri->params; + } else if ( relative_uri->params ) { + tmp_uri.params = relative_uri->params; +@@ -707,7 +728,14 @@ struct uri * resolve_uri ( const struct uri *base_uri, + /* Create demangled URI */ + new_uri = uri_dup ( &tmp_uri ); + free ( tmp_path ); ++ free ( tmp_epath ); + return new_uri; ++ ++ free ( tmp_path ); ++ err_path: ++ free ( tmp_epath ); ++ err_epath: ++ return NULL; + } + + /** +@@ -746,6 +774,7 @@ static struct uri * tftp_uri ( struct sockaddr *sa_server, + if ( asprintf ( &path, "/%s", filename ) < 0 ) + goto err_path; + tmp.path = path; ++ tmp.epath = path; + + /* Demangle URI */ + uri = uri_dup ( &tmp ); +diff --git a/src/include/ipxe/uri.h b/src/include/ipxe/uri.h +index 3879a0e730..e5b7c8616b 100644 +--- a/src/include/ipxe/uri.h ++++ b/src/include/ipxe/uri.h +@@ -46,6 +46,20 @@ struct parameters; + * scheme = "ftp", user = "joe", password = "secret", + * host = "insecure.org", port = "8081", path = "/hidden/path/to", + * query = "what=is", fragment = "this" ++ * ++ * The URI syntax includes a percent-encoding mechanism that can be ++ * used to represent characters that would otherwise not be possible, ++ * such as a '/' character within the password field. These encodings ++ * are decoded during the URI parsing stage, thereby allowing protocol ++ * implementations to consume the raw field values directly without ++ * further decoding. ++ * ++ * Some protocols (such as HTTP) communicate using URI-encoded values. ++ * For these protocols, the original encoded substring must be ++ * retained verbatim since the choice of whether or not to encode a ++ * particular character may have significance to the receiving ++ * application. We therefore retain the originally-encoded substrings ++ * for the path, query, and fragment fields. + */ + struct uri { + /** Reference count */ +@@ -62,12 +76,14 @@ struct uri { + const char *host; + /** Port number */ + const char *port; +- /** Path */ ++ /** Path (after URI decoding) */ + const char *path; +- /** Query */ +- const char *query; +- /** Fragment */ +- const char *fragment; ++ /** Path (with original URI encoding) */ ++ const char *epath; ++ /** Query (with original URI encoding) */ ++ const char *equery; ++ /** Fragment (with original URI encoding) */ ++ const char *efragment; + /** Form parameters */ + struct parameters *params; + } __attribute__ (( packed )); +@@ -100,8 +116,9 @@ enum uri_fields { + URI_HOST = URI_FIELD ( host ), + URI_PORT = URI_FIELD ( port ), + URI_PATH = URI_FIELD ( path ), +- URI_QUERY = URI_FIELD ( query ), +- URI_FRAGMENT = URI_FIELD ( fragment ), ++ URI_EPATH = URI_FIELD ( epath ), ++ URI_EQUERY = URI_FIELD ( equery ), ++ URI_EFRAGMENT = URI_FIELD ( efragment ), + URI_FIELDS + }; + +diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c +index 01bb496b21..fd94b5f083 100644 +--- a/src/net/tcp/httpcore.c ++++ b/src/net/tcp/httpcore.c +@@ -614,8 +614,8 @@ int http_open ( struct interface *xfer, struct http_method *method, + + /* Calculate request URI length */ + memset ( &request_uri, 0, sizeof ( request_uri ) ); +- request_uri.path = ( uri->path ? uri->path : "/" ); +- request_uri.query = uri->query; ++ request_uri.epath = ( uri->epath ? uri->epath : "/" ); ++ request_uri.equery = uri->equery; + request_uri_len = + ( format_uri ( &request_uri, NULL, 0 ) + 1 /* NUL */); + +diff --git a/src/tests/uri_test.c b/src/tests/uri_test.c +index 92c2f90371..929ab36325 100644 +--- a/src/tests/uri_test.c ++++ b/src/tests/uri_test.c +@@ -149,8 +149,10 @@ static void uri_okx ( struct uri *uri, struct uri *expected, const char *file, + okx ( uristrcmp ( uri->host, expected->host ) == 0, file, line ); + okx ( uristrcmp ( uri->port, expected->port ) == 0, file, line ); + okx ( uristrcmp ( uri->path, expected->path ) == 0, file, line ); +- okx ( uristrcmp ( uri->query, expected->query ) == 0, file, line ); +- okx ( uristrcmp ( uri->fragment, expected->fragment ) == 0, file, line); ++ okx ( uristrcmp ( uri->epath, expected->epath ) == 0, file, line ); ++ okx ( uristrcmp ( uri->equery, expected->equery ) == 0, file, line ); ++ okx ( uristrcmp ( uri->efragment, expected->efragment ) == 0, ++ file, line); + okx ( uri->params == expected->params, file, line ); + } + #define uri_ok( uri, expected ) uri_okx ( uri, expected, __FILE__, __LINE__ ) +@@ -490,25 +492,33 @@ static struct uri_test uri_empty = { + /** Basic HTTP URI */ + static struct uri_test uri_boot_ipxe_org = { + "http://boot.ipxe.org/demo/boot.php", +- { .scheme = "http", .host = "boot.ipxe.org", .path = "/demo/boot.php" } ++ { .scheme = "http", .host = "boot.ipxe.org", ++ .path = "/demo/boot.php", .epath = "/demo/boot.php" }, + }; + + /** Basic opaque URI */ + static struct uri_test uri_mailto = { + "mailto:ipxe-devel@lists.ipxe.org", +- { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" } ++ { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" }, ++}; ++ ++/** Basic host-only URI */ ++static struct uri_test uri_host = { ++ "http://boot.ipxe.org", ++ { .scheme = "http", .host = "boot.ipxe.org" }, + }; + + /** Basic path-only URI */ + static struct uri_test uri_path = { + "/var/lib/tftpboot/pxelinux.0", +- { .path = "/var/lib/tftpboot/pxelinux.0" }, ++ { .path = "/var/lib/tftpboot/pxelinux.0", ++ .epath ="/var/lib/tftpboot/pxelinux.0" }, + }; + + /** Path-only URI with escaped characters */ + static struct uri_test uri_path_escaped = { + "/hello%20world%3F", +- { .path = "/hello world?" }, ++ { .path = "/hello world?", .epath = "/hello%20world%3F" }, + }; + + /** HTTP URI with all the trimmings */ +@@ -521,8 +531,9 @@ static struct uri_test uri_http_all = { + .host = "example.com", + .port = "3001", + .path = "/~foo/cgi-bin/foo.pl", +- .query = "a=b&c=d", +- .fragment = "bit", ++ .epath = "/~foo/cgi-bin/foo.pl", ++ .equery = "a=b&c=d", ++ .efragment = "bit", + }, + }; + +@@ -533,8 +544,9 @@ static struct uri_test uri_http_escaped = { + .scheme = "https", + .host = "test.ipxe.org", + .path = "/wtf?\n", +- .query = "kind#of/uri is", +- .fragment = "this?", ++ .epath = "/wtf%3F%0A", ++ .equery = "kind%23of/uri%20is", ++ .efragment = "this%3F", + }, + }; + +@@ -550,8 +562,9 @@ static struct uri_test uri_http_escaped_improper = { + .scheme = "https", + .host = "test.ipxe.org", + .path = "/wtf?\n", +- .query = "kind#of/uri is", +- .fragment = "this?", ++ .epath = "/wt%66%3f\n", ++ .equery = "kind%23of/uri is", ++ .efragment = "this?", + }, + }; + +@@ -562,6 +575,7 @@ static struct uri_test uri_ipv6 = { + .scheme = "http", + .host = "[2001:ba8:0:1d4::6950:5845]", + .path = "/", ++ .epath = "/", + }, + }; + +@@ -573,6 +587,7 @@ static struct uri_test uri_ipv6_port = { + .host = "[2001:ba8:0:1d4::6950:5845]", + .port = "8001", + .path = "/boot", ++ .epath = "/boot", + }, + }; + +@@ -583,6 +598,7 @@ static struct uri_test uri_ipv6_local = { + .scheme = "http", + .host = "[fe80::69ff:fe50:5845%net0]", + .path = "/ipxe", ++ .epath = "/ipxe", + }, + }; + +@@ -598,6 +614,7 @@ static struct uri_test uri_ipv6_local_non_conforming = { + .scheme = "http", + .host = "[fe80::69ff:fe50:5845%net0]", + .path = "/ipxe", ++ .epath = "/ipxe", + }, + }; + +@@ -625,6 +642,7 @@ static struct uri_test uri_file_absolute = { + { + .scheme = "file", + .path = "/boot/script.ipxe", ++ .epath = "/boot/script.ipxe", + }, + }; + +@@ -635,6 +653,7 @@ static struct uri_test uri_file_volume = { + .scheme = "file", + .host = "hpilo", + .path = "/boot/script.ipxe", ++ .epath = "/boot/script.ipxe", + }, + }; + +@@ -736,6 +755,7 @@ static struct uri_pxe_test uri_pxe_absolute = { + .scheme = "http", + .host = "not.a.tftp", + .path = "/uri", ++ .epath = "/uri", + }, + "http://not.a.tftp/uri", + }; +@@ -754,6 +774,7 @@ static struct uri_pxe_test uri_pxe_absolute_path = { + .scheme = "tftp", + .host = "192.168.0.2", + .path = "//absolute/path", ++ .epath = "//absolute/path", + }, + "tftp://192.168.0.2//absolute/path", + }; +@@ -772,6 +793,7 @@ static struct uri_pxe_test uri_pxe_relative_path = { + .scheme = "tftp", + .host = "192.168.0.3", + .path = "/relative/path", ++ .epath = "/relative/path", + }, + "tftp://192.168.0.3/relative/path", + }; +@@ -790,8 +812,9 @@ static struct uri_pxe_test uri_pxe_icky = { + .scheme = "tftp", + .host = "10.0.0.6", + .path = "/C:\\tftpboot\\icky#path", ++ .epath = "/C:\\tftpboot\\icky#path", + }, +- "tftp://10.0.0.6/C%3A\\tftpboot\\icky%23path", ++ "tftp://10.0.0.6/C:\\tftpboot\\icky#path", + }; + + /** PXE URI with custom port */ +@@ -810,6 +833,7 @@ static struct uri_pxe_test uri_pxe_port = { + .host = "192.168.0.1", + .port = "4069", + .path = "//another/path", ++ .epath = "//another/path", + }, + "tftp://192.168.0.1:4069//another/path", + }; +@@ -873,6 +897,7 @@ static struct uri_params_test uri_params = { + .scheme = "http", + .host = "boot.ipxe.org", + .path = "/demo/boot.php", ++ .epath = "/demo/boot.php", + }, + NULL, + uri_params_list, +@@ -902,6 +927,7 @@ static struct uri_params_test uri_named_params = { + .host = "192.168.100.4", + .port = "3001", + .path = "/register", ++ .epath = "/register", + }, + "foo", + uri_named_params_list, +@@ -917,6 +943,7 @@ static void uri_test_exec ( void ) { + uri_parse_format_dup_ok ( &uri_empty ); + uri_parse_format_dup_ok ( &uri_boot_ipxe_org ); + uri_parse_format_dup_ok ( &uri_mailto ); ++ uri_parse_format_dup_ok ( &uri_host ); + uri_parse_format_dup_ok ( &uri_path ); + uri_parse_format_dup_ok ( &uri_path_escaped ); + uri_parse_format_dup_ok ( &uri_http_all ); +diff --git a/src/usr/imgmgmt.c b/src/usr/imgmgmt.c +index f8d149153a..b7fc8293d4 100644 +--- a/src/usr/imgmgmt.c ++++ b/src/usr/imgmgmt.c +@@ -58,8 +58,8 @@ int imgdownload ( struct uri *uri, unsigned long timeout, + memcpy ( &uri_redacted, uri, sizeof ( uri_redacted ) ); + uri_redacted.user = NULL; + uri_redacted.password = NULL; +- uri_redacted.query = NULL; +- uri_redacted.fragment = NULL; ++ uri_redacted.equery = NULL; ++ uri_redacted.efragment = NULL; + uri_string_redacted = format_uri_alloc ( &uri_redacted ); + if ( ! uri_string_redacted ) { + rc = -ENOMEM; + + diff --git a/ipxe.spec b/ipxe.spec new file mode 100644 index 0000000..20956b3 --- /dev/null +++ b/ipxe.spec @@ -0,0 +1,259 @@ +%global formats rom +%global qemuroms 10222000 10ec8029 8086100e 10ec8139 1af41000 80861209 808610d3 15ad07b0 +%global buildarches x86_64 +%global debug_package %{nil} +%global enable_i386 0 + +Name: ipxe +Version: 1.21.1 +Release: 5 +Summary: A network boot loader +Epoch: 1 +License: GPLv2 with additional permissions and BSD +URL: http://ipxe.org/ +Source0: https://github.com/ipxe/ipxe/archive/v%{version}.tar.gz +Patch0001: 0001-build-customize-configuration.patch +Patch0002: 0002-Use-spec-compliant-timeouts.patch +Patch0003: 0003-librm-Use-explicit-operand-size-when-pushing-a-label.patch + +Patch6000: backport-avoid-infinite-loop-on-allocation-failure-in.patch +Patch6001: backport-ensure-that-pci_read_config-initialises-all-fields.patch +Patch6002: backport-do-not-clear-current-working-url-when-executing-embedded-image.patch +Patch6003: backport-retain-original-encodings-for-path-query-and-fragment-fields.patch +Patch6004: backport-allow-for-relative-uris-that-include-colons-within-the-path.patch + +%ifarch %{buildarches} +BuildRequires: perl-interpreter perl-Getopt-Long syslinux mtools genisoimage edk2-devel +BuildRequires: xz-devel gcc binutils-devel +Obsoletes: gpxe <= 1.0.1 + +%package bootimgs +Summary: Network boot loader images in bootable USB, CD, floppy and GRUB formats +BuildArch: noarch +Obsoletes: gpxe-bootimgs <= 1.0.1 + +%package roms +Summary: Network boot loader roms in .rom format +Requires: %{name}-roms-qemu = %{epoch}:%{version}-%{release} +BuildArch: noarch +Obsoletes: gpxe-roms <= 1.0.1 + +%package roms-qemu +Summary: Network boot loader roms supported by QEMU, .rom format +BuildArch: noarch +Obsoletes: gpxe-roms-qemu <= 1.0.1 + +%description bootimgs +iPXE is an open source network bootloader. It provides a direct +replacement for proprietary PXE ROMs, with many extra features such as +DNS, HTTP, iSCSI, etc. + +This package contains the iPXE boot images in USB, CD, floppy, and PXE +UNDI formats. + +%description roms +iPXE is an open source network bootloader. It provides a direct +replacement for proprietary PXE ROMs, with many extra features such as +DNS, HTTP, iSCSI, etc. + +This package contains the iPXE roms in .rom format. + + +%description roms-qemu +iPXE is an open source network bootloader. It provides a direct +replacement for proprietary PXE ROMs, with many extra features such as +DNS, HTTP, iSCSI, etc. + +This package contains the iPXE ROMs for devices emulated by QEMU, in +.rom format. +%endif + +%description +iPXE is an open source network bootloader. It provides a direct +replacement for proprietary PXE ROMs, with many extra features such as +DNS, HTTP, iSCSI, etc. + +%prep +%setup -q -n %{name}-%{version} +%autopatch -p1 + + +%build +%ifarch %{buildarches} +cd src + +rm -rf drivers/net/ath/ath9k + +make_ipxe() { + make %{?_smp_mflags} \ + NO_WERROR=1 V=1 \ + GITVERSION=%{hash} \ + "$@" +} + +make_ipxe bin-i386-efi/ipxe.efi bin-x86_64-efi/ipxe.efi bin-x86_64-linux/tests.linux \ + %if 0%{?enable i386} + bin-i386-linux/tests.linux + %endif + +make_ipxe ISOLINUX_BIN=/usr/share/syslinux/isolinux.bin \ + bin/undionly.kpxe bin/ipxe.{dsk,iso,usb,lkrn} \ + allroms + +mkdir bin-combined +for rom in %{qemuroms}; do + make_ipxe CONFIG=qemu bin/${rom}.rom +%if 0%{?enable_i386} + make_ipxe CONFIG=qemu bin-i386-efi/${rom}.efidrv +%endif + make_ipxe CONFIG=qemu bin-x86_64-efi/${rom}.efidrv + vid="0x${rom%%????}" + did="0x${rom#????}" + EfiRom -f "$vid" -i "$did" --pci23 \ + -b bin/${rom}.rom \ +%if 0%{?enable_i386} + -ec bin-i386-efi/${rom}.efidrv \ +%endif + -ec bin-x86_64-efi/${rom}.efidrv \ + -o bin-combined/${rom}.rom + EfiRom -d bin-combined/${rom}.rom + truncate -s \>256K bin-combined/${rom}.rom + test $(stat -c '%s' bin-combined/${rom}.rom) -le $((256 * 1024)) +done + +%endif + +%install +%ifarch %{buildarches} +mkdir -p %{buildroot}/%{_datadir}/%{name}/ +mkdir -p %{buildroot}/%{_datadir}/%{name}.efi/ +pushd src/bin/ + +cp -a undionly.kpxe ipxe.{iso,usb,dsk,lkrn} %{buildroot}/%{_datadir}/%{name}/ + +for fmt in %{formats};do + for img in *.${fmt};do + if [ -e $img ]; then + cp -a $img %{buildroot}/%{_datadir}/%{name}/ + echo %{_datadir}/%{name}/$img >> ../../${fmt}.list + fi + done +done +popd + +cp -a src/bin-i386-efi/ipxe.efi %{buildroot}/%{_datadir}/%{name}/ipxe-i386.efi +cp -a src/bin-x86_64-efi/ipxe.efi %{buildroot}/%{_datadir}/%{name}/ipxe-x86_64.efi + +for fmt in rom ;do + for rom in %{qemuroms} ; do + sed -i -e "/\/${rom}.${fmt}/d" ${fmt}.list + echo %{_datadir}/%{name}/${rom}.${fmt} >> qemu.${fmt}.list + done +done +for rom in %{qemuroms}; do + cp src/bin-combined/${rom}.rom %{buildroot}/%{_datadir}/%{name}.efi/ + echo %{_datadir}/%{name}.efi/${rom}.rom >> qemu.rom.list +done +%endif + +%check +%ifarch %{buildarches} +cd ~/rpmbuild/BUILD/%{name}-%{version}/src/bin-x86_64-linux/ +./tests.linux +%if 0%{?enable_i386} +cd ~/rpmbuild/BUILD/%{name}-%{version}/src/bin-i386-linux/ +./tests.linux +%endif +%endif + +%ifarch %{buildarches} +%files bootimgs +%defattr(-,root,root) +%license COPYING COPYING.GPLv2 COPYING.UBDL +%dir %{_datadir}/%{name} +%{_datadir}/%{name}/ipxe.iso +%{_datadir}/%{name}/ipxe.usb +%{_datadir}/%{name}/ipxe.dsk +%{_datadir}/%{name}/ipxe.lkrn +%{_datadir}/%{name}/ipxe-i386.efi +%{_datadir}/%{name}/ipxe-x86_64.efi +%{_datadir}/%{name}/undionly.kpxe + +%files roms -f rom.list +%defattr(-,root,root) +%license COPYING COPYING.GPLv2 COPYING.UBDL +%dir %{_datadir}/%{name} + +%files roms-qemu -f qemu.rom.list +%defattr(-,root,root) +%license COPYING COPYING.GPLv2 COPYING.UBDL +%dir %{_datadir}/%{name} +%dir %{_datadir}/%{name}.efi +%endif + +%changelog +* Fri Mar 15 2024 herengui <herengui@kylinsec.com.cn> - 1:1.21.1-5 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: fix errors when compiling with binutils-2.41 + +* Wed Nov 23 2022 zhangqiumiao <zhangqiumiao1@huawei.com> - 1:1.21.1-4 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:[pci] Ensure that pci_read_config() initialises all fields + [image] Do not clear current working URI when executing embedded image + [uri] Retain original encodings for path, query, and fragment fields + [uri] Allow for relative URIs that include colons within the path + +* Sat Mar 26 2022 wangkerong <wangkerong@h-partners.com> - 1.21.1-3 +- enable test + +* Wed Jun 09 2021 wangkerong <wangkerong@huawei.com> - 1.21.1-2 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC: round commmunity patch fix Avoid infinite loop on allocation failure + +* Wed Feb 03 2021 gaihuiying <gaihuiying1@huawei.com> - 1.21.1-1 +- Type:requirement +- Id:NA +- SUG:NA +- DESC: update ipxe to 1.21.1 + +* Thu Sep 03 2020 zhouyihang <zhouyihang3@huawei.com> - 1.20.1-2 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC: add epoch for roms-qemu when required by roms + +* Tue Jun 23 2020 zhujunhao <zhujunhao8@huawei.com> - 1.20.1-1 +- update to 1.20.1 + +* Mon Jan 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 20190125-5 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC: add bootimgs roms roms-qemu subpackages + +* Fri Nov 29 2019 openEuler Buildteam <buildteam@openeuler.org> - 20190125-4 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC: fix build error on x86_64 + +* Sat Oct 19 2019 openEuler Buildteam <buildteam@openeuler.org> - 20190125-3 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC:change the directory of the license files + +* Thu Oct 10 2019 openEuler Buildteam <buildteam@openeuler.org> - 20190125-2 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:add requires + +* Thu Sep 19 2019 openEuler Buildteam <buildteam@openeuler.org> - 20190125-1 +- Package init @@ -0,0 +1 @@ +ad39d9bd2d6d77f3702c4015203426ae v1.21.1.tar.gz |