chantra / rpms / rpm

Forked from rpms/rpm 2 years ago
Clone
Blob Blame History Raw
From aabaa6c6587c37b84a1b9cfd98bff31f1b69345e Mon Sep 17 00:00:00 2001
From: chantra <chantr4@gmail.com>
Date: Wed, 16 Feb 2022 17:00:09 -0800
Subject: [PATCH 24/30] [rpm2extents] create footer struct and helpers

new extents_footer and extents_footer_offset struct with a function to
load offsets from an FD.
Change existing code to use new struct/functions
---
 lib/rpmchecksig.c         | 16 +++-------------
 lib/rpmextents.c          | 26 +++++++++++++++++---------
 lib/rpmextents_internal.h | 31 ++++++++++++++++++++++++++++++-
 rpm2extents.c             | 23 ++++-------------------
 4 files changed, 54 insertions(+), 42 deletions(-)

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