All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marek Behún" <marek.behun@nic.cz>
To: Stefan Roese <sr@denx.de>
Cc: u-boot@lists.denx.de, pali@kernel.org,
	"Chris Packham" <judge.packham@gmail.com>,
	"Baruch Siach" <baruch@tkos.co.il>,
	"Dennis Gilmore" <dgilmore@redhat.com>,
	"Mario Six" <mario.six@gdsys.cc>,
	"Jon Nettleton" <jon@solid-run.com>,
	"Andrew Lunn" <andrew@lunn.ch>,
	"Marek Behún" <marek.behun@nic.cz>
Subject: [PATCH u-boot-marvell v2 26/39] tools: kwboot: Round up header size to 128 B when patching
Date: Tue,  7 Sep 2021 11:58:24 +0200	[thread overview]
Message-ID: <20210907095837.14042-27-marek.behun@nic.cz> (raw)
In-Reply-To: <20210907095837.14042-1-marek.behun@nic.cz>

From: Pali Rohár <pali@kernel.org>

The beginning of image data must be sent in a separate xmodem block;
the block must not contain end of header with the beginning of data.

Therefore we need to ensure that the image header size is a multiple of
xmodem block size (which is 128 B).

Read the file into a malloc()ed buffer of enough size instead of
mmap()ing it. (If we are going to move the data, most of the pages will
be dirty anyway.) Then move the payload if header size needs to be
increased.

Signed-off-by: Pali Rohár <pali@kernel.org>
[ refactored ]
Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
 tools/kwboot.c | 89 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 77 insertions(+), 12 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 4807a0cf8d..7e9a09a209 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -25,7 +25,6 @@
 #include <stdint.h>
 #include <termios.h>
 #include <time.h>
-#include <sys/mman.h>
 #include <sys/stat.h>
 
 /*
@@ -706,11 +705,12 @@ out:
 }
 
 static void *
-kwboot_mmap_image(const char *path, size_t *size)
+kwboot_read_image(const char *path, size_t *size, size_t reserve)
 {
 	int rc, fd;
 	struct stat st;
 	void *img;
+	off_t tot;
 
 	rc = -1;
 	img = NULL;
@@ -723,17 +723,30 @@ kwboot_mmap_image(const char *path, size_t *size)
 	if (rc)
 		goto out;
 
-	img = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-	if (img == MAP_FAILED) {
-		img = NULL;
+	img = malloc(st.st_size + reserve);
+	if (!img)
 		goto out;
+
+	tot = 0;
+	while (tot < st.st_size) {
+		ssize_t rd = read(fd, img + tot, st.st_size - tot);
+
+		if (rd < 0)
+			goto out;
+
+		tot += rd;
+
+		if (!rd && tot < st.st_size) {
+			errno = EIO;
+			goto out;
+		}
 	}
 
 	rc = 0;
 	*size = st.st_size;
 out:
 	if (rc && img) {
-		munmap(img, st.st_size);
+		free(img);
 		img = NULL;
 	}
 	if (fd >= 0)
@@ -769,8 +782,39 @@ kwboot_img_is_secure(void *img)
 	return 0;
 }
 
+static void
+kwboot_img_grow_hdr(void *img, size_t *size, size_t grow)
+{
+	uint32_t hdrsz, datasz, srcaddr;
+	struct main_hdr_v1 *hdr = img;
+	uint8_t *data;
+
+	srcaddr = le32_to_cpu(hdr->srcaddr);
+
+	hdrsz = kwbheader_size(img);
+	data = (uint8_t *)img + srcaddr;
+	datasz = *size - srcaddr;
+
+	/* only move data if there is not enough space */
+	if (hdrsz + grow > srcaddr) {
+		size_t need = hdrsz + grow - srcaddr;
+
+		/* move data by enough bytes */
+		memmove(data + need, data, datasz);
+
+		hdr->srcaddr = cpu_to_le32(srcaddr + need);
+		*size += need;
+	}
+
+	if (kwbimage_version(img) == 1) {
+		hdrsz += grow;
+		hdr->headersz_msb = hdrsz >> 16;
+		hdr->headersz_lsb = cpu_to_le16(hdrsz & 0xffff);
+	}
+}
+
 static int
-kwboot_img_patch_hdr(void *img, size_t size)
+kwboot_img_patch_hdr(void *img, size_t *size)
 {
 	int rc;
 	struct main_hdr_v1 *hdr;
@@ -783,7 +827,7 @@ kwboot_img_patch_hdr(void *img, size_t size)
 	rc = -1;
 	hdr = img;
 
-	if (size < hdrsz) {
+	if (*size < hdrsz) {
 		errno = EINVAL;
 		goto out;
 	}
@@ -797,7 +841,7 @@ kwboot_img_patch_hdr(void *img, size_t size)
 
 	hdrsz = kwbheader_size(hdr);
 
-	if (size < hdrsz) {
+	if (*size < hdrsz) {
 		errno = EINVAL;
 		goto out;
 	}
@@ -844,6 +888,12 @@ kwboot_img_patch_hdr(void *img, size_t size)
 		break;
 	}
 
+	if (hdrsz > le32_to_cpu(hdr->srcaddr) ||
+	    *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize)) {
+		errno = EINVAL;
+		goto out;
+	}
+
 	is_secure = kwboot_img_is_secure(img);
 
 	if (hdr->blockid != IBR_HDR_UART_ID) {
@@ -858,8 +908,23 @@ kwboot_img_patch_hdr(void *img, size_t size)
 		hdr->blockid = IBR_HDR_UART_ID;
 	}
 
+	if (hdrsz % KWBOOT_XM_BLKSZ) {
+		size_t offset = (KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ) %
+				KWBOOT_XM_BLKSZ;
+
+		if (is_secure) {
+			fprintf(stderr, "Cannot align image with secure header\n");
+			errno = EINVAL;
+			goto out;
+		}
+
+		kwboot_printv("Aligning image header to Xmodem block size\n");
+		kwboot_img_grow_hdr(img, size, offset);
+	}
+
 	hdr->checksum = kwboot_hdr_csum8(hdr) - csum;
 
+	*size = le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize);
 	rc = 0;
 out:
 	return rc;
@@ -986,13 +1051,13 @@ main(int argc, char **argv)
 	}
 
 	if (imgpath) {
-		img = kwboot_mmap_image(imgpath, &size);
+		img = kwboot_read_image(imgpath, &size, KWBOOT_XM_BLKSZ);
 		if (!img) {
 			perror(imgpath);
 			goto out;
 		}
 
-		rc = kwboot_img_patch_hdr(img, size);
+		rc = kwboot_img_patch_hdr(img, &size);
 		if (rc) {
 			fprintf(stderr, "%s: Invalid image.\n", imgpath);
 			goto out;
@@ -1035,7 +1100,7 @@ out:
 		close(tty);
 
 	if (img)
-		munmap(img, size);
+		free(img);
 
 	return rv;
 
-- 
2.32.0


  parent reply	other threads:[~2021-09-07 10:04 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-07  9:57 [PATCH u-boot-marvell v2 00/39] kwboot higher baudrate Marek Behún
2021-09-07  9:57 ` [PATCH u-boot-marvell v2 01/39] tools: kwbimage: Fix printf format warning Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 02/39] tools: kwboot: Fix buffer overflow in kwboot_terminal() Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 03/39] tools: kwboot: Make the quit sequence buffer const Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 04/39] tools: kwboot: Refactor and fix writing buffer Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 05/39] tools: kwboot: Print version information header Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 06/39] tools: kwboot: Fix kwboot_xm_sendblock() function when kwboot_tty_recv() fails Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 07/39] tools: kwboot: Fix return type of kwboot_xm_makeblock() function Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 08/39] tools: kwboot: Fix comparison of integers with different size Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 09/39] tools: kwboot: Fix printing progress Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 10/39] tools: kwboot: Print newline on error when progress was not completed Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 11/39] tools: kwboot: Split sending image into header and data stages Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 12/39] tools: kwboot: Use a function to check whether received byte is a Xmodem reply Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 13/39] tools: kwboot: Allow non-xmodem text output from BootROM only in a specific case Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 14/39] tools: kwboot: Print new line after SPL output Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 15/39] tools: kwboot: Allow greater timeout when executing header code Marek Behún
2021-09-07 21:53   ` Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 16/39] tools: kwboot: Prevent waiting indefinitely if no xmodem reply is received Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 19/39] tools: kwbimage: Simplify iteration over version 1 optional headers Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 20/39] tools: kwboot: Don't patch image header if signed Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 21/39] tools: kwboot: Patch source address in image header Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 22/39] tools: kwboot: Patch destination address to DDR area for SPI image Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 23/39] tools: kwbimage: Refactor image_version() Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 24/39] tools: kwbimage: Refactor kwbimage header size determination Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 25/39] tools: kwbimage: Update comments describing kwbimage v1 structures Marek Behún
2021-09-07  9:58 ` Marek Behún [this message]
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 27/39] tools: kwboot: Explicitly check against size of struct main_hdr_v1 Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 28/39] tools: kwboot: Support higher baudrates when booting via UART Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 30/39] tools: kwboot: Check whether baudrate was set to requested value Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 32/39] kwboot: Disable tty interbyte timeout Marek Behún
2021-09-07 11:51   ` Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 33/39] tools: kwboot: Disable non-blocking mode Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 34/39] tools: kwboot: Cosmetic fix Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 35/39] tools: kwboot: Avoid code repetition in kwboot_img_patch() Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 36/39] tools: kwboot: Update file header Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 37/39] tools: kwboot: Add Pali and Marek as authors Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 38/39] doc/kwboot.1: Update man page Marek Behún
2021-09-07  9:58 ` [PATCH u-boot-marvell v2 39/39] MAINTAINERS: Add entry for kwbimage / kwboot tools Marek Behún

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=20210907095837.14042-27-marek.behun@nic.cz \
    --to=marek.behun@nic.cz \
    --cc=andrew@lunn.ch \
    --cc=baruch@tkos.co.il \
    --cc=dgilmore@redhat.com \
    --cc=jon@solid-run.com \
    --cc=judge.packham@gmail.com \
    --cc=mario.six@gdsys.cc \
    --cc=pali@kernel.org \
    --cc=sr@denx.de \
    --cc=u-boot@lists.denx.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.