From 23de40cd360841db94c08a509eb12cc6a8eb1b28 Mon Sep 17 00:00:00 2001
From: Daniel Kolesa <daniel@octaforge.org>
Date: Thu, 15 Jun 2023 19:31:00 +0200
Subject: [PATCH] adb: fix endianness issues

Fixed missing endian swaps in several places both in package
creation and package reading. Also made sure that the digest
used for signature checking always comes out the same regardless
of host byte order (previously the signature would only be
compatible with the byte order it was created on and fail
anywhere else).

Ref https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10900
---
 src/adb.c        |  8 ++++++--
 src/app_mkpkg.c  | 10 +++++-----
 src/extract_v3.c |  8 ++++----
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/adb.c b/src/adb.c
index 93ae8af0..e0cc3bcf 100644
--- a/src/adb.c
+++ b/src/adb.c
@@ -696,8 +696,10 @@ static adb_val_t adb_w_blob_raw(struct adb *db, apk_blob_t b)
 
 adb_val_t adb_w_int(struct adb *db, uint32_t val)
 {
-	if (val >= 0x10000000)
+	if (val >= 0x10000000) {
+		val = htole32(val);
 		return ADB_VAL(ADB_TYPE_INT_32, adb_w_data1(db, &val, sizeof val, sizeof val));
+	}
 	return ADB_VAL(ADB_TYPE_INT, val);
 }
 
@@ -1035,7 +1037,7 @@ int adb_s_field_by_name(const struct adb_object_schema *schema, const char *name
 int adb_c_header(struct apk_ostream *os, struct adb *db)
 {
 	struct adb_file_header hdr = {
-		.magic = ADB_FORMAT_MAGIC,
+		.magic = htole32(ADB_FORMAT_MAGIC),
 		.schema = htole32(db->schema),
 	};
 	return apk_ostream_write(os, &hdr, sizeof hdr);
@@ -1166,6 +1168,8 @@ static int adb_digest_v0_signature(struct apk_digest_ctx *dctx, uint32_t schema,
 {
 	int r;
 
+	/* it is imporant to normalize this before including it in the digest */
+	schema = htole32(schema);
 	if ((r = apk_digest_ctx_update(dctx, &schema, sizeof schema)) != 0 ||
 	    (r = apk_digest_ctx_update(dctx, sig0, sizeof *sig0)) != 0 ||
 	    (r = apk_digest_ctx_update(dctx, md.ptr, md.len)) != 0)
diff --git a/src/app_mkpkg.c b/src/app_mkpkg.c
index f1cffc5f..74c8db83 100644
--- a/src/app_mkpkg.c
+++ b/src/app_mkpkg.c
@@ -195,12 +195,12 @@ static int mkpkg_process_dirent(void *pctx, int dirfd, const char *entry)
 	case S_IFBLK:
 	case S_IFCHR:
 	case S_IFIFO:
-		ft.dev.mode = fi.mode & S_IFMT;
-		ft.dev.dev = fi.device;
+		ft.dev.mode = htole16(fi.mode & S_IFMT);
+		ft.dev.dev = htole64(fi.device);
 		target = APK_BLOB_STRUCT(ft.dev);
 		break;
 	case S_IFLNK:
-		ft.symlink.mode = fi.mode & S_IFMT;
+		ft.symlink.mode = htole16(fi.mode & S_IFMT);
 		r = readlinkat(dirfd, entry, ft.symlink.target, sizeof ft.symlink.target);
 		if (r < 0) return r;
 		target = APK_BLOB_PTR_LEN((void*)&ft.symlink, sizeof(ft.symlink.mode) + r);
@@ -385,8 +385,8 @@ static int mkpkg_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a
 			if (!APK_BLOB_IS_NULL(target)) continue;
 			if (!sz) continue;
 			struct adb_data_package hdr = {
-				.path_idx = i,
-				.file_idx = j,
+				.path_idx = htole32(i),
+				.file_idx = htole32(j),
 			};
 			int n = apk_pathbuilder_pushb(&ctx->pb, filename);
 			adb_c_block_data(
diff --git a/src/extract_v3.c b/src/extract_v3.c
index de265edc..a28eae1a 100644
--- a/src/extract_v3.c
+++ b/src/extract_v3.c
@@ -51,7 +51,7 @@ static int apk_extract_v3_file(struct apk_extract_ctx *ectx, off_t sz, struct ap
 		uint16_t mode;
 
 		if (target.len < 2) return -APKE_ADB_SCHEMA;
-		mode = *(uint16_t*)target.ptr;
+		mode = le16toh(*(uint16_t*)target.ptr);
 		target.ptr += 2;
 		target.len -= 2;
 		switch (mode) {
@@ -62,7 +62,7 @@ static int apk_extract_v3_file(struct apk_extract_ctx *ectx, off_t sz, struct ap
 			struct unaligned64 {
 				uint64_t value;
 			} __attribute__((packed));
-			fi.device = ((struct unaligned64 *)target.ptr)->value;
+			fi.device = le64toh(((struct unaligned64 *)target.ptr)->value);
 			break;
 		case S_IFLNK:
 			target_path = alloca(target.len + 1);
@@ -168,8 +168,8 @@ static int apk_extract_v3_data_block(struct adb *db, struct adb_block *b, struct
 	sz -= sizeof *hdr;
 	if (IS_ERR(hdr)) return PTR_ERR(hdr);
 
-	if (hdr->path_idx != ctx->cur_path ||
-	    hdr->file_idx != ctx->cur_file ||
+	if (le32toh(hdr->path_idx) != ctx->cur_path ||
+	    le32toh(hdr->file_idx) != ctx->cur_file ||
 	    sz != adb_ro_int(&ctx->file, ADBI_FI_SIZE)) {
 		// got data for some unexpected file
 		return -APKE_ADB_BLOCK;
-- 
GitLab