diff mbox series

[1/3] stream_interface: Fix 16kB issue on save_stream

Message ID 20240430124316.1714467-1-Michael.Glembotzki@iris-sensing.com
State New
Headers show
Series [1/3] stream_interface: Fix 16kB issue on save_stream | expand

Commit Message

Michael Glembotzki April 30, 2024, 12:43 p.m. UTC
The first two cpio blocks are alternately read into tmpfd. Previously it
was assumed that both files fit into a 16 kB buffer.

Signed-off-by: Michael Glembotzki <Michael.Glembotzki@iris-sensing.com>
---
 core/stream_interface.c | 72 +++++++++++++++++++++++------------------
 include/util.h          |  1 -
 2 files changed, 41 insertions(+), 32 deletions(-)
diff mbox series

Patch

diff --git a/core/stream_interface.c b/core/stream_interface.c
index 5ebaca68..5f3ad2e3 100644
--- a/core/stream_interface.c
+++ b/core/stream_interface.c
@@ -374,7 +374,6 @@  static int save_stream(int fdin, struct swupdate_cfg *software)
 {
 	unsigned char *buf;
 	int fdout = -1, ret, len;
-	const int bufsize = 16 * 1024;
 	int tmpfd = -1;
 	char tmpfilename[MAX_IMAGE_FNAME];
 	struct filehdr fdh;
@@ -383,7 +382,11 @@  static int save_stream(int fdin, struct swupdate_cfg *software)
 	char output_file[MAX_IMAGE_FNAME];
 	const char* TMPDIR = get_tmpdir();
 	bool encrypted_sw_desc = false;
+	int files = 1;
 
+#ifdef CONFIG_SIGNED_IMAGES
+	files = 2; // sw-description and sw-description.sig
+#endif
 #ifdef CONFIG_ENCRYPTED_SW_DESCRIPTION
 	encrypted_sw_desc = true;
 #endif
@@ -392,7 +395,7 @@  static int save_stream(int fdin, struct swupdate_cfg *software)
 
 	snprintf(tmpfilename, sizeof(tmpfilename), "%s/%s", TMPDIR, SW_TMP_OUTPUT);
 
-	buf = (unsigned char *)malloc(bufsize);
+	buf = (unsigned char *)malloc(sizeof(struct new_ascii_header));
 	if (!buf) {
 		ERROR("OOM when saving stream");
 		return -ENOMEM;
@@ -410,39 +413,46 @@  static int save_stream(int fdin, struct swupdate_cfg *software)
 		ret = -EFAULT;
 		goto no_copy_output;
 	}
-	len = read(fdin, buf, bufsize);
-	if (len < 0) {
-		ERROR("Reading from file failed, error %d", errno);
-		ret = -EFAULT;
-		goto no_copy_output;
-	}
-	if (get_cpiohdr(buf, &fdh) < 0) {
-		ERROR("CPIO Header corrupted, cannot be parsed");
-		ret = -EINVAL;
-		goto no_copy_output;
-	}
 
 	/*
-	 * Make an estimation for sw-description and signature.
-	 * Signature cannot be very big - if it is, it is an attack.
-	 * So let a buffer just for the signature - tmpsize is enough for both
-	 * sw-description and sw-description.sig, if any.
+	 * Copy first two cpio blocks (sw-description and sw-description.sig) into tmpfd
 	 */
-	tmpsize = SWUPDATE_ALIGN(fdh.size + fdh.namesize + sizeof(struct new_ascii_header) + bufsize - len,
-			bufsize);
-	ret = copy_write(&tmpfd, buf, len);  /* copy the first buffer */
-	if (ret < 0) {
-		ret =  -EIO;
-		goto no_copy_output;
-	}
+	while (files-- > 0) {
+		len = fill_buffer(fdin, buf, sizeof(struct new_ascii_header));
+		if (len < 0) {
+			ERROR("Reading from file failed, error %d", errno);
+			ret = -EFAULT;
+			goto no_copy_output;
+		}
 
-	/*
-	 * copy enough bytes to have sw-description and sw-description.sig
-	 */
-	ret = cpfiles(fdin, tmpfd, tmpsize);
-	if (ret < 0) {
-		ret =  -EIO;
-		goto no_copy_output;
+		if (get_cpiohdr(buf, &fdh) < 0) {
+			ERROR("CPIO Header corrupted, cannot be parsed");
+			ret = -EINVAL;
+			goto no_copy_output;
+		}
+
+		ret = copy_write(&tmpfd, buf, len);
+		if (ret < 0) {
+			ret =  -EIO;
+			goto no_copy_output;
+		}
+
+		/*
+		 * calc remaining bytes of the cpio block
+		 */
+		tmpsize = sizeof(struct new_ascii_header) + fdh.namesize;
+		tmpsize += NPAD_BYTES(tmpsize) + fdh.size;
+		tmpsize += NPAD_BYTES(tmpsize);
+		tmpsize -= sizeof(struct new_ascii_header);
+
+		/*
+		 * copy the remaining bytes to have a complete cpio block
+		 */
+		ret = cpfiles(fdin, tmpfd, tmpsize);
+		if (ret < 0) {
+			ret =  -EIO;
+			goto no_copy_output;
+		}
 	}
 	lseek(tmpfd, 0, SEEK_SET);
 	offset = 0;
diff --git a/include/util.h b/include/util.h
index e1350633..77da1b17 100644
--- a/include/util.h
+++ b/include/util.h
@@ -33,7 +33,6 @@ 
 #define AES_256_KEY_LEN	32
 
 #define HWID_REGEXP_PREFIX	"#RE:"
-#define SWUPDATE_ALIGN(A,S)    (((A) + (S) - 1) & ~((S) - 1))
 
 #define BOOTVAR_TRANSACTION "recovery_status"