mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 2/2] fip: add function to parse FIP from a buffer
Date: Mon, 17 Feb 2025 13:25:38 +0100	[thread overview]
Message-ID: <20250217122538.3216703-2-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20250217122538.3216703-1-s.hauer@pengutronix.de>

So far we can only parse a FIP image from a file. Provide fip_parse_buf()
to open a FIP image from a buffer.
The bulk of fip_parse() can be re-used for that. While at it use
read_file_2() to read in the FIP image.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/fiptool.h |  4 +++
 lib/fip.c         | 92 ++++++++++++++++++++++++++---------------------
 2 files changed, 56 insertions(+), 40 deletions(-)

diff --git a/include/fiptool.h b/include/fiptool.h
index bc42f7edd6..bb63a79c16 100644
--- a/include/fiptool.h
+++ b/include/fiptool.h
@@ -38,6 +38,7 @@ struct fip_state {
 	size_t nr_image_descs;
 	int verbose;
 	void *buffer;
+	bool buf_no_free;
 };
 
 #define pr_verbose(...) do { \
@@ -68,6 +69,9 @@ struct fip_image_desc *fip_lookup_image_desc_from_uuid(struct fip_state *fip,
 
 struct fip_image_desc *fip_lookup_image_desc_from_opt(struct fip_state *fip, char **arg);
 
+int fip_parse_buf(struct fip_state *fip, void *buf, size_t size,
+		  fip_toc_header_t *toc_header_out);
+
 int fip_parse(struct fip_state *fip,
 		     const char *filename, fip_toc_header_t *toc_header_out);
 
diff --git a/lib/fip.c b/lib/fip.c
index 806f172318..23e82098da 100644
--- a/lib/fip.c
+++ b/lib/fip.c
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <libfile.h>
+#include <fs.h>
 
 #include <fip.h>
 #include <fiptool.h>
@@ -93,7 +94,9 @@ void fip_free(struct fip_state *fip)
 
 	ASSERT(fip->nr_image_descs == 0);
 
-	free(fip->buffer);
+	if (!fip->buf_no_free)
+		free(fip->buffer);
+
 	free(fip);
 }
 
@@ -155,44 +158,20 @@ struct fip_image_desc *fip_lookup_image_desc_from_opt(struct fip_state *fip, cha
 	return NULL;
 }
 
-int fip_parse(struct fip_state *fip,
-		     const char *filename, fip_toc_header_t *toc_header_out)
+static int fip_do_parse_buf(struct fip_state *fip, void *buf, size_t size,
+			    fip_toc_header_t *toc_header_out)
 {
-	struct stat st;
-	int fd;
 	char *bufend;
 	fip_toc_header_t *toc_header;
 	fip_toc_entry_t *toc_entry;
 	int terminated = 0;
-	size_t st_size;
-
-	if (fip->buffer)
-		return -EBUSY;
-
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		pr_err("open %s: %m\n", filename);
-		return -errno;
-	}
-
-	if (fstat(fd, &st) == -1) {
-		pr_err("fstat %s: %m\n", filename);
-		return -errno;
-	}
-
-	st_size = st.st_size;
 
-	fip->buffer = xmalloc(st_size);
-	if (read_full(fd, fip->buffer, st_size) != st_size) {
-		pr_err("Failed to read %s: %m\n", filename);
-		return -errno;
-	}
+	fip->buffer = buf;
 
-	bufend = fip->buffer + st_size;
-	close(fd);
+	bufend = fip->buffer + size;
 
-	if (st_size < sizeof(fip_toc_header_t)) {
-		pr_err("FIP %s is truncated\n", filename);
+	if (size < sizeof(fip_toc_header_t)) {
+		pr_err("FIP is truncated\n");
 		return -ENODATA;
 	}
 
@@ -200,8 +179,8 @@ int fip_parse(struct fip_state *fip,
 	toc_entry = (fip_toc_entry_t *)(toc_header + 1);
 
 	if (toc_header->name != TOC_HEADER_NAME) {
-		pr_err("%s is not a FIP file: unknown magic = 0x%08x\n",
-		       filename, toc_header->name);
+		pr_err("not a FIP file: unknown magic = 0x%08x\n",
+		       toc_header->name);
 		return -EINVAL;
 	}
 
@@ -230,13 +209,12 @@ int fip_parse(struct fip_state *fip,
 		image->buf_no_free = true;
 		/* Overflow checks before memory copy. */
 		if (toc_entry->size > (uint64_t)-1 - toc_entry->offset_address) {
-			pr_err("FIP %s is corrupted: entry size exceeds 64 bit address space\n",
-			       filename);
+			pr_err("FIP is corrupted: entry size exceeds 64 bit address space\n");
 			return -EINVAL;
 		}
-		if (toc_entry->size + toc_entry->offset_address > st_size) {
-			pr_err("FIP %s is corrupted: entry size (0x%llx) exceeds FIP file size (0x%zx)\n",
-				filename, toc_entry->size + toc_entry->offset_address, st_size);
+		if (toc_entry->size + toc_entry->offset_address > size) {
+			pr_err("FIP is corrupted: entry size (0x%llx) exceeds FIP file size (0x%zx)\n",
+				toc_entry->size + toc_entry->offset_address, size);
 			return -EINVAL;
 		}
 
@@ -261,14 +239,48 @@ int fip_parse(struct fip_state *fip,
 	}
 
 	if (terminated == 0) {
-		pr_err("FIP %s does not have a ToC terminator entry\n",
-		    filename);
+		pr_err("FIP does not have a ToC terminator entry\n");
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
+int fip_parse_buf(struct fip_state *fip, void *buf, size_t size,
+			    fip_toc_header_t *toc_header_out)
+{
+	if (fip->buffer)
+		return -EBUSY;
+
+	fip->buf_no_free = true;
+
+	return fip_do_parse_buf(fip, buf, size, toc_header_out);
+}
+
+int fip_parse(struct fip_state *fip,
+		     const char *filename, fip_toc_header_t *toc_header_out)
+{
+	size_t size;
+	int ret;
+	void *buf;
+
+	if (fip->buffer)
+		return -EBUSY;
+
+	ret = read_file_2(filename, &size, &buf, FILESIZE_MAX);
+	if (ret) {
+		pr_err("open %s: %m\n", filename);
+		return ret;
+	}
+
+	ret = fip_parse_buf(fip, buf, size, toc_header_out);
+
+	if (ret)
+		free(buf);
+
+	return ret;
+}
+
 static struct fip_image *fip_read_image_from_file(const uuid_t *uuid, const char *filename)
 {
 	struct stat st;
-- 
2.39.5




      reply	other threads:[~2025-02-17 12:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-17 12:25 [PATCH 1/2] fip: Store image data in single buffer Sascha Hauer
2025-02-17 12:25 ` Sascha Hauer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250217122538.3216703-2-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox