[Concept,18/26] boot: pxe: Add pxe_process_str() for nul-terminated strings

Message ID 20260110202906.187370-19-sjg@u-boot.org
State New
Headers
Series boot: pxe: Add three-phase API and fix memory leaks |

Commit Message

Simon Glass Jan. 10, 2026, 8:28 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

The pxe_process() function requires a nul-terminated string at the given
address.

Rename the function to pxe_process_str() to make this requirement clear,
and add a note to the documentation.

Add a size parameter to pxe_process()

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 boot/ext_pxe_common.c            |  2 +-
 boot/pxe_utils.c                 | 17 +++++++++++++++--
 cmd/pxe.c                        |  2 +-
 cmd/sysboot.c                    |  2 +-
 doc/develop/bootstd/extlinux.rst |  2 +-
 doc/develop/bootstd/pxelinux.rst |  2 +-
 include/pxe_utils.h              | 16 ++++++++++++++--
 7 files changed, 34 insertions(+), 9 deletions(-)
  

Patch

diff --git a/boot/ext_pxe_common.c b/boot/ext_pxe_common.c
index 930e54ea84d..2bc76a4d0fb 100644
--- a/boot/ext_pxe_common.c
+++ b/boot/ext_pxe_common.c
@@ -115,7 +115,7 @@  int extlinux_boot(struct udevice *dev, struct bootflow *bflow,
 			return log_msg_ret("elb", ret);
 		plat->ctx.restart = restart;
 		addr = map_to_sysmem(bflow->buf);
-		ret = pxe_process(&plat->ctx, addr, false);
+		ret = pxe_process_str(&plat->ctx, addr, false);
 	}
 	if (ret)
 		return log_msg_ret("elb", -EFAULT);
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 6416ee3ddff..3f751f25bea 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -1325,11 +1325,12 @@  static struct pxe_menu *pxe_prepare(struct pxe_context *ctx,
 	return cfg;
 }
 
-int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt)
+int pxe_process(struct pxe_context *ctx, ulong addr, ulong size, bool prompt)
 {
 	struct pxe_menu *cfg;
 
-	cfg = pxe_prepare(ctx, pxefile_addr_r, prompt);
+	ctx->pxe_file_size = size;
+	cfg = pxe_prepare(ctx, addr, prompt);
 	if (!cfg)
 		return 1;
 
@@ -1340,6 +1341,18 @@  int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt)
 	return 0;
 }
 
+int pxe_process_str(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt)
+{
+	void *ptr;
+	int len;
+
+	ptr = map_sysmem(pxefile_addr_r, 0);
+	len = strnlen(ptr, SZ_64K);
+	unmap_sysmem(ptr);
+
+	return pxe_process(ctx, pxefile_addr_r, len, prompt);
+}
+
 int pxe_probe(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt)
 {
 	ctx->cfg = pxe_prepare(ctx, pxefile_addr_r, prompt);
diff --git a/cmd/pxe.c b/cmd/pxe.c
index 9f40f13c201..2cda2597f28 100644
--- a/cmd/pxe.c
+++ b/cmd/pxe.c
@@ -286,7 +286,7 @@  do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 		printf("Out of memory\n");
 		return CMD_RET_FAILURE;
 	}
-	ret = pxe_process(&ctx, pxefile_addr_r, false);
+	ret = pxe_process(&ctx, pxefile_addr_r, ctx.pxe_file_size, false);
 	pxe_destroy_ctx(&ctx);
 	if (ret)
 		return CMD_RET_FAILURE;
diff --git a/cmd/sysboot.c b/cmd/sysboot.c
index e6f89c999cc..b48272b2126 100644
--- a/cmd/sysboot.c
+++ b/cmd/sysboot.c
@@ -119,7 +119,7 @@  static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
 		return 1;
 	}
 
-	ret = pxe_process(&ctx, pxefile_addr_r, prompt);
+	ret = pxe_process(&ctx, pxefile_addr_r, ctx.pxe_file_size, prompt);
 	pxe_destroy_ctx(&ctx);
 	if (ret)
 		return CMD_RET_FAILURE;
diff --git a/doc/develop/bootstd/extlinux.rst b/doc/develop/bootstd/extlinux.rst
index bf27dc57aaa..0c8526d7325 100644
--- a/doc/develop/bootstd/extlinux.rst
+++ b/doc/develop/bootstd/extlinux.rst
@@ -21,7 +21,7 @@  When invoked on a bootdev, this bootmeth searches for the file and creates a
 bootflow if found.
 
 When the bootflow is booted, the bootmeth calls ``pxe_setup_ctx()`` to set up
-the context, then ``pxe_process()`` to process the file. Depending on the
+the context, then ``pxe_process_str()`` to process the file. Depending on the
 contents, this may boot an operating system or provide a list of options to
 the user, perhaps with a timeout.
 
diff --git a/doc/develop/bootstd/pxelinux.rst b/doc/develop/bootstd/pxelinux.rst
index c4b7fbb4c9c..c3d5e6f2408 100644
--- a/doc/develop/bootstd/pxelinux.rst
+++ b/doc/develop/bootstd/pxelinux.rst
@@ -19,7 +19,7 @@  bootflow if found. See
 a full description of the search procedure.
 
 When the bootflow is booted, the bootmeth calls ``pxe_setup_ctx()`` to set up
-the context, then ``pxe_process()`` to process the file. Depending on the
+the context, then ``pxe_process_str()`` to process the file. Depending on the
 contents, this may boot an Operating System or provide a list of options to the
 user, perhaps with a timeout.
 
diff --git a/include/pxe_utils.h b/include/pxe_utils.h
index 50e0c0c6b93..e8045511c6a 100644
--- a/include/pxe_utils.h
+++ b/include/pxe_utils.h
@@ -366,14 +366,26 @@  int pxe_setup_ctx(struct pxe_context *ctx, pxe_getfile_func getfile,
  */
 void pxe_destroy_ctx(struct pxe_context *ctx);
 
+/**
+ * pxe_process_str() - Process a PXE file through to boot
+ *
+ * Note: The file at @pxefile_addr_r must be a nul-terminated string.
+ *
+ * @ctx: PXE context created with pxe_setup_ctx()
+ * @pxefile_addr_r: Address of config to process
+ * @prompt: Force a prompt for the user
+ */
+int pxe_process_str(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt);
+
 /**
  * pxe_process() - Process a PXE file through to boot
  *
  * @ctx: PXE context created with pxe_setup_ctx()
- * @pxefile_addr_r: Address to load file
+ * @addr: Address of config to process
+ * @size: Size of continue to process
  * @prompt: Force a prompt for the user
  */
-int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt);
+int pxe_process(struct pxe_context *ctx, ulong addr, ulong size, bool prompt);
 
 /**
  * pxe_get_file_size() - Read the value of the 'filesize' environment variable