2f13d7
From aabaa6c6587c37b84a1b9cfd98bff31f1b69345e Mon Sep 17 00:00:00 2001
2f13d7
From: chantra <chantr4@gmail.com>
2f13d7
Date: Wed, 16 Feb 2022 17:00:09 -0800
2f13d7
Subject: [PATCH 24/30] [rpm2extents] create footer struct and helpers
2f13d7
2f13d7
new extents_footer and extents_footer_offset struct with a function to
2f13d7
load offsets from an FD.
2f13d7
Change existing code to use new struct/functions
2f13d7
---
2f13d7
 lib/rpmchecksig.c         | 16 +++-------------
2f13d7
 lib/rpmextents.c          | 26 +++++++++++++++++---------
2f13d7
 lib/rpmextents_internal.h | 31 ++++++++++++++++++++++++++++++-
2f13d7
 rpm2extents.c             | 23 ++++-------------------
2f13d7
 4 files changed, 54 insertions(+), 42 deletions(-)
2f13d7
2f13d7
diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c
2f13d7
index dc1726a18..729f79f9f 100644
2f13d7
--- a/lib/rpmchecksig.c
2f13d7
+++ b/lib/rpmchecksig.c
2f13d7
@@ -223,29 +223,19 @@ exit:
2f13d7
 
2f13d7
 static int rpmpkgVerifySigsTranscoded(FD_t fd){
2f13d7
     rpm_loff_t current;
2f13d7
-    uint64_t magic;
2f13d7
-    rpm_loff_t offset;
2f13d7
     int32_t rc;
2f13d7
     size_t len;
2f13d7
     uint64_t content_len;
2f13d7
     char *content = NULL;
2f13d7
+    struct extents_footer_t footer;
2f13d7
 
2f13d7
     current = Ftell(fd);
2f13d7
 
2f13d7
-    if(Fseek(fd, -(sizeof(magic) + 3 * sizeof(offset) ), SEEK_END) < 0) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: failed to seek for offset\n"));
2f13d7
+    if(extentsFooterFromFD(fd, &footer) != RPMRC_OK) {
2f13d7
 	rc = -1;
2f13d7
 	goto exit;
2f13d7
     }
2f13d7
-
2f13d7
-    len = sizeof(offset);
2f13d7
-    if (Fread(&offset, len, 1, fd) != len) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to read Signature Verification offset\n"));
2f13d7
-	rc = -1;
2f13d7
-	goto exit;
2f13d7
-    }
2f13d7
-
2f13d7
-    if(Fseek(fd,  offset, SEEK_SET) < 0) {
2f13d7
+    if(Fseek(fd, footer.offsets.checksig_offset, SEEK_SET) < 0) {
2f13d7
 	rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to seek signature verification offset\n"));
2f13d7
 	rc = -1;
2f13d7
 	goto exit;
2f13d7
diff --git a/lib/rpmextents.c b/lib/rpmextents.c
2f13d7
index 015277751..46b7aadff 100644
2f13d7
--- a/lib/rpmextents.c
2f13d7
+++ b/lib/rpmextents.c
2f13d7
@@ -3,13 +3,16 @@
2f13d7
 
2f13d7
 #include <rpm/rpmlog.h>
2f13d7
 #include <rpm/rpmio.h>
2f13d7
+#include <string.h>
2f13d7
+#include <errno.h>
2f13d7
+
2f13d7
 
2f13d7
 #include "lib/rpmextents_internal.h"
2f13d7
 
2f13d7
-rpmRC isTranscodedRpm(FD_t fd) {
2f13d7
+rpmRC extentsFooterFromFD(FD_t fd, struct extents_footer_t *footer) {
2f13d7
+
2f13d7
     rpmRC rc = RPMRC_NOTFOUND;
2f13d7
     rpm_loff_t current;
2f13d7
-    extents_magic_t magic;
2f13d7
     size_t len;
2f13d7
 
2f13d7
     // If the file is not seekable, we cannot detect whether or not it is transcoded.
2f13d7
@@ -18,19 +21,19 @@ rpmRC isTranscodedRpm(FD_t fd) {
2f13d7
     }
2f13d7
     current = Ftell(fd);
2f13d7
 
2f13d7
-    if(Fseek(fd, -(sizeof(magic)), SEEK_END) < 0) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("isTranscodedRpm: failed to seek for magic\n"));
2f13d7
+    len = sizeof(struct extents_footer_t);
2f13d7
+    if(Fseek(fd, -len, SEEK_END) < 0) {
2f13d7
+	rpmlog(RPMLOG_ERR, _("isTranscodedRpm: failed to seek for footer: %s\n"), strerror(errno));
2f13d7
 	rc = RPMRC_FAIL;
2f13d7
 	goto exit;
2f13d7
     }
2f13d7
-    len = sizeof(magic);
2f13d7
-    if (Fread(&magic, len, 1, fd) != len) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("isTranscodedRpm: unable to read magic\n"));
2f13d7
+    if (Fread(footer, len, 1, fd) != len) {
2f13d7
+	rpmlog(RPMLOG_ERR, _("isTranscodedRpm: unable to read footer\n"));
2f13d7
 	rc = RPMRC_FAIL;
2f13d7
 	goto exit;
2f13d7
     }
2f13d7
-    if (magic != EXTENTS_MAGIC) {
2f13d7
-	rpmlog(RPMLOG_DEBUG, _("isTranscodedRpm: not transcoded\n"));
2f13d7
+    if (footer->magic != EXTENTS_MAGIC) {
2f13d7
+	rpmlog(RPMLOG_ERR, _("isTranscodedRpm: not transcoded\n"));
2f13d7
 	rc = RPMRC_NOTFOUND;
2f13d7
 	goto exit;
2f13d7
     }
2f13d7
@@ -43,4 +46,9 @@ exit:
2f13d7
     return rc;
2f13d7
 }
2f13d7
 
2f13d7
+rpmRC isTranscodedRpm(FD_t fd) {
2f13d7
+    struct extents_footer_t footer;
2f13d7
+    return extentsFooterFromFD(fd, &footer);
2f13d7
+}
2f13d7
+
2f13d7
 
2f13d7
diff --git a/lib/rpmextents_internal.h b/lib/rpmextents_internal.h
2f13d7
index 57cecfc31..f0c29c807 100644
2f13d7
--- a/lib/rpmextents_internal.h
2f13d7
+++ b/lib/rpmextents_internal.h
2f13d7
@@ -7,6 +7,10 @@ extern "C" {
2f13d7
 
2f13d7
 #include <stdint.h>
2f13d7
 
2f13d7
+/** \ingroup rpmextents
2f13d7
+ * RPM extents library
2f13d7
+ */
2f13d7
+
2f13d7
 /* magic value at end of file (64 bits) that indicates this is a transcoded
2f13d7
  * rpm.
2f13d7
  */
2f13d7
@@ -14,9 +18,34 @@ extern "C" {
2f13d7
 
2f13d7
 typedef uint64_t extents_magic_t;
2f13d7
 
2f13d7
+struct __attribute__ ((__packed__)) extents_footer_offsets_t {
2f13d7
+    off64_t checksig_offset;
2f13d7
+    off64_t table_offset;
2f13d7
+    off64_t csum_offset;
2f13d7
+};
2f13d7
+
2f13d7
+struct __attribute__ ((__packed__)) extents_footer_t {
2f13d7
+    struct extents_footer_offsets_t offsets;
2f13d7
+    extents_magic_t magic;
2f13d7
+};
2f13d7
+
2f13d7
+
2f13d7
+/** \ingroup rpmextents
2f13d7
+ * Read the RPM Extents footer from a file descriptor.
2f13d7
+ * @param fd		The FD_t of the transcoded RPM
2f13d7
+ * @param[out] footer	A pointer to an allocated extents_footer_t with a copy of the footer.
2f13d7
+ * @return		RPMRC_OK on success, RPMRC_NOTFOUND if not a transcoded file, RPMRC_FAIL on any failure.
2f13d7
+ */
2f13d7
+rpmRC extentsFooterFromFD(FD_t fd, struct extents_footer_t *footer);
2f13d7
+
2f13d7
+/** \ingroup rpmextents
2f13d7
+ * Check if a RPM is a transcoded RPM
2f13d7
+ * @param fd	The FD_t of the transcoded RPM
2f13d7
+ * return	RPMRC_OK on success, RPMRC_NOTFOUND if not a transcoded file, RPMRC_FAIL on any failure.
2f13d7
+ */
2f13d7
 rpmRC isTranscodedRpm(FD_t fd);
2f13d7
 
2f13d7
 #ifdef __cplusplus
2f13d7
 }
2f13d7
 #endif
2f13d7
-#endif
2f13d7
+#endif /* _RPMEXTENTS_INTERNAL_H */
2f13d7
diff --git a/rpm2extents.c b/rpm2extents.c
2f13d7
index e1a19fedb..7dd5128de 100644
2f13d7
--- a/rpm2extents.c
2f13d7
+++ b/rpm2extents.c
2f13d7
@@ -405,25 +405,10 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
2f13d7
 	goto exit;
2f13d7
     }
2f13d7
     zeros = _free(zeros);
2f13d7
-    if (Fwrite(&validation_pos, len, 1, fdo) != len) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("Unable to write offset of validation output\n"));
2f13d7
-	rc = RPMRC_FAIL;
2f13d7
-	goto exit;
2f13d7
-    }
2f13d7
-    if (Fwrite(&digest_table_pos, len, 1, fdo) != len) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("Unable to write offset of digest table\n"));
2f13d7
-	rc = RPMRC_FAIL;
2f13d7
-	goto exit;
2f13d7
-    }
2f13d7
-    if (Fwrite(&digest_pos, len, 1, fdo) != len) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("Unable to write offset of validation table\n"));
2f13d7
-	rc = RPMRC_FAIL;
2f13d7
-	goto exit;
2f13d7
-    }
2f13d7
-    extents_magic_t magic = EXTENTS_MAGIC;
2f13d7
-    len = sizeof(magic);
2f13d7
-    if (Fwrite(&magic, len, 1, fdo) != len) {
2f13d7
-	rpmlog(RPMLOG_ERR, _("Unable to write magic\n"));
2f13d7
+    struct extents_footer_t footer = {.offsets = {validation_pos, digest_table_pos, digest_pos}, .magic = EXTENTS_MAGIC};
2f13d7
+    len = sizeof(footer);
2f13d7
+    if (Fwrite(&footer, len, 1, fdo) != len) {
2f13d7
+	rpmlog(RPMLOG_ERR, _("Unable to write footer\n"));
2f13d7
 	rc = RPMRC_FAIL;
2f13d7
 	goto exit;
2f13d7
     }
2f13d7
-- 
2f13d7
2.35.1
2f13d7