michal-grzedzicki / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone
Richard Phibel bd001b
From: Richard Phibel <richardphibel@meta.com>
Richard Phibel bd001b
Richard Phibel bd001b
Subject: RPM with Copy on Write: add deny list mechanism
Richard Phibel bd001b
Richard Phibel bd001b
commit 3431550e6c92ba4bc6d091cb244f70c158dfbbaa
Richard Phibel bd001b
Author: Richard Phibel <richardphibel@meta.com>
Richard Phibel bd001b
Date:   Wed Oct 19 23:05:17 2022 +0200
Richard Phibel bd001b
Richard Phibel bd001b
    RPM with Copy on Write: add deny list mechanism
Richard Phibel bd001b
    
Richard Phibel bd001b
    A couple of issues were encountered when using RPM CoW for some
Richard Phibel bd001b
    packages. This change adds a deny list mechanism to disable RPM CoW for
Richard Phibel bd001b
    specific packages.
Richard Phibel bd001b
Richard Phibel bd001b
Signed-off-by: Richard Phibel <richardphibel@meta.com>
Richard Phibel bd001b
Richard Phibel bd001b
diff --git a/build/pack.c b/build/pack.c
Richard Phibel bd001b
index 8d6f74935ebb8a4d65aa2bcb666825a99162be9c..e2f05b6412d3e0d814a1160a0dcdfad5c323a8f8 100644
Richard Phibel bd001b
--- a/build/pack.c
Richard Phibel bd001b
+++ b/build/pack.c
Richard Phibel bd001b
@@ -493,7 +493,7 @@ static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
Richard Phibel bd001b
     }
Richard Phibel bd001b
 
Richard Phibel bd001b
     /* Write the lead section into the package. */
Richard Phibel bd001b
-    if (rpmLeadWrite(fd, pkg->header)) {
Richard Phibel bd001b
+    if (rpmLeadWriteFromHeader(fd, pkg->header)) {
Richard Phibel bd001b
 	rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"), Fstrerror(fd));
Richard Phibel bd001b
 	goto exit;
Richard Phibel bd001b
     }
Richard Phibel bd001b
diff --git a/lib/package.c b/lib/package.c
Richard Phibel bd001b
index 90bd0d8a719353e8965c140b40e2dceef80a2ed1..fd41abbf6b4df07afa2caf1c47d9724765ee84e8 100644
Richard Phibel bd001b
--- a/lib/package.c
Richard Phibel bd001b
+++ b/lib/package.c
Richard Phibel bd001b
@@ -412,11 +412,7 @@ rpmRC rpmReadPackageRaw(FD_t fd, Header * sigp, Header * hdrp)
Richard Phibel bd001b
     Header h = NULL;
Richard Phibel bd001b
     Header sigh = NULL;
Richard Phibel bd001b
 
Richard Phibel bd001b
-    rpmRC rc = rpmLeadRead(fd, &msg;;
Richard Phibel bd001b
-    if (rc != RPMRC_OK)
Richard Phibel bd001b
-	goto exit;
Richard Phibel bd001b
-
Richard Phibel bd001b
-    rc = hdrblobRead(fd, 1, 0, RPMTAG_HEADERSIGNATURES, sigblob, &msg;;
Richard Phibel bd001b
+    rpmRC rc = hdrblobRead(fd, 1, 0, RPMTAG_HEADERSIGNATURES, sigblob, &msg;;
Richard Phibel bd001b
     if (rc != RPMRC_OK)
Richard Phibel bd001b
 	goto exit;
Richard Phibel bd001b
 
Richard Phibel bd001b
diff --git a/lib/rpmlead.c b/lib/rpmlead.c
Richard Phibel bd001b
index 45b1c6f8edacb65549ba8d321de8f6ce8cef4503..82105122724a8efb071aecefdb278ef96ea5e70d 100644
Richard Phibel bd001b
--- a/lib/rpmlead.c
Richard Phibel bd001b
+++ b/lib/rpmlead.c
Richard Phibel bd001b
@@ -24,24 +24,6 @@ static unsigned char const lead_magic[] = {
Richard Phibel bd001b
     RPMLEAD_MAGIC0, RPMLEAD_MAGIC1, RPMLEAD_MAGIC2, RPMLEAD_MAGIC3
Richard Phibel bd001b
 };
Richard Phibel bd001b
 
Richard Phibel bd001b
-/** \ingroup lead
Richard Phibel bd001b
- * The lead data structure.
Richard Phibel bd001b
- * The lead needs to be 8 byte aligned.
Richard Phibel bd001b
- * @deprecated The lead (except for signature_type) is legacy.
Richard Phibel bd001b
- * @todo Don't use any information from lead.
Richard Phibel bd001b
- */
Richard Phibel bd001b
-struct rpmlead_s {
Richard Phibel bd001b
-    unsigned char magic[4];
Richard Phibel bd001b
-    unsigned char major;
Richard Phibel bd001b
-    unsigned char minor;
Richard Phibel bd001b
-    short type;
Richard Phibel bd001b
-    short archnum;
Richard Phibel bd001b
-    char name[66];
Richard Phibel bd001b
-    short osnum;
Richard Phibel bd001b
-    short signature_type;       /*!< Signature header type (RPMSIG_HEADERSIG) */
Richard Phibel bd001b
-    char reserved[16];      /*!< Pad to 96 bytes -- 8 byte aligned! */
Richard Phibel bd001b
-};
Richard Phibel bd001b
-
Richard Phibel bd001b
 static int rpmLeadFromHeader(Header h, struct rpmlead_s *l)
Richard Phibel bd001b
 {
Richard Phibel bd001b
     if (h != NULL) {
Richard Phibel bd001b
@@ -70,13 +52,23 @@ static int rpmLeadFromHeader(Header h, struct rpmlead_s *l)
Richard Phibel bd001b
 }
Richard Phibel bd001b
 
Richard Phibel bd001b
 /* The lead needs to be 8 byte aligned */
Richard Phibel bd001b
-rpmRC rpmLeadWrite(FD_t fd, Header h)
Richard Phibel bd001b
+rpmRC rpmLeadWriteFromHeader(FD_t fd, Header h)
Richard Phibel bd001b
 {
Richard Phibel bd001b
     rpmRC rc = RPMRC_FAIL;
Richard Phibel bd001b
     struct rpmlead_s l;
Richard Phibel bd001b
 
Richard Phibel bd001b
-    if (rpmLeadFromHeader(h, &l)) {
Richard Phibel bd001b
-	
Richard Phibel bd001b
+    if (rpmLeadFromHeader(h, &l)) {	
Richard Phibel bd001b
+	rc = rpmLeadWrite(fd, l);
Richard Phibel bd001b
+    }
Richard Phibel bd001b
+
Richard Phibel bd001b
+    return rc;
Richard Phibel bd001b
+}
Richard Phibel bd001b
+
Richard Phibel bd001b
+/* The lead needs to be 8 byte aligned */
Richard Phibel bd001b
+rpmRC rpmLeadWrite(FD_t fd, struct rpmlead_s l)
Richard Phibel bd001b
+{
Richard Phibel bd001b
+    rpmRC rc = RPMRC_FAIL;
Richard Phibel bd001b
+
Richard Phibel bd001b
 	l.type = htons(l.type);
Richard Phibel bd001b
 	l.archnum = htons(l.archnum);
Richard Phibel bd001b
 	l.osnum = htons(l.osnum);
Richard Phibel bd001b
@@ -84,7 +76,6 @@ rpmRC rpmLeadWrite(FD_t fd, Header h)
Richard Phibel bd001b
 	    
Richard Phibel bd001b
 	if (Fwrite(&l, 1, sizeof(l), fd) == sizeof(l))
Richard Phibel bd001b
 	    rc = RPMRC_OK;
Richard Phibel bd001b
-    }
Richard Phibel bd001b
 
Richard Phibel bd001b
     return rc;
Richard Phibel bd001b
 }
Richard Phibel bd001b
@@ -107,6 +98,11 @@ static rpmRC rpmLeadCheck(struct rpmlead_s *lead, char **msg)
Richard Phibel bd001b
 }
Richard Phibel bd001b
 
Richard Phibel bd001b
 rpmRC rpmLeadRead(FD_t fd, char **emsg)
Richard Phibel bd001b
+{
Richard Phibel bd001b
+    return rpmLeadReadAndReturn(fd, emsg, NULL);
Richard Phibel bd001b
+}
Richard Phibel bd001b
+
Richard Phibel bd001b
+rpmRC rpmLeadReadAndReturn(FD_t fd, char **emsg, struct rpmlead_s * ret)
Richard Phibel bd001b
 {
Richard Phibel bd001b
     rpmRC rc = RPMRC_OK;
Richard Phibel bd001b
     struct rpmlead_s l;
Richard Phibel bd001b
@@ -136,5 +132,8 @@ rpmRC rpmLeadRead(FD_t fd, char **emsg)
Richard Phibel bd001b
 	    free(err);
Richard Phibel bd001b
     }
Richard Phibel bd001b
 
Richard Phibel bd001b
+	if (ret)
Richard Phibel bd001b
+		*ret = l;
Richard Phibel bd001b
+
Richard Phibel bd001b
     return rc;
Richard Phibel bd001b
 }
Richard Phibel bd001b
diff --git a/lib/rpmlead.h b/lib/rpmlead.h
Richard Phibel bd001b
index 9d86a8d73b3250d3c306b3a3ac4a33486e6920ec..8a592abc1d0e69822f438c4c7b248cce1cb5ee72 100644
Richard Phibel bd001b
--- a/lib/rpmlead.h
Richard Phibel bd001b
+++ b/lib/rpmlead.h
Richard Phibel bd001b
@@ -19,13 +19,39 @@ extern "C" {
Richard Phibel bd001b
 
Richard Phibel bd001b
 #define RPMLEAD_SIZE 96         /*!< Don't rely on sizeof(struct) */
Richard Phibel bd001b
 
Richard Phibel bd001b
+/** \ingroup lead
Richard Phibel bd001b
+ * The lead data structure.
Richard Phibel bd001b
+ * The lead needs to be 8 byte aligned.
Richard Phibel bd001b
+ * @deprecated The lead (except for signature_type) is legacy.
Richard Phibel bd001b
+ * @todo Don't use any information from lead.
Richard Phibel bd001b
+ */
Richard Phibel bd001b
+struct rpmlead_s {
Richard Phibel bd001b
+    unsigned char magic[4];
Richard Phibel bd001b
+    unsigned char major;
Richard Phibel bd001b
+    unsigned char minor;
Richard Phibel bd001b
+    short type;
Richard Phibel bd001b
+    short archnum;
Richard Phibel bd001b
+    char name[66];
Richard Phibel bd001b
+    short osnum;
Richard Phibel bd001b
+    short signature_type;       /*!< Signature header type (RPMSIG_HEADERSIG) */
Richard Phibel bd001b
+    char reserved[16];      /*!< Pad to 96 bytes -- 8 byte aligned! */
Richard Phibel bd001b
+};
Richard Phibel bd001b
+
Richard Phibel bd001b
 /** \ingroup lead
Richard Phibel bd001b
  * Write lead to file handle.
Richard Phibel bd001b
  * @param fd		file handle
Richard Phibel bd001b
  * @param h		package header
Richard Phibel bd001b
  * @return		RPMRC_OK on success, RPMRC_FAIL on error
Richard Phibel bd001b
  */
Richard Phibel bd001b
-rpmRC rpmLeadWrite(FD_t fd, Header h);
Richard Phibel bd001b
+rpmRC rpmLeadWriteFromHeader(FD_t fd, Header h);
Richard Phibel bd001b
+
Richard Phibel bd001b
+/** \ingroup lead
Richard Phibel bd001b
+ * Write lead to file handle.
Richard Phibel bd001b
+ * @param fd		file handle
Richard Phibel bd001b
+ * @param l		lead
Richard Phibel bd001b
+ * @return		RPMRC_OK on success, RPMRC_FAIL on error
Richard Phibel bd001b
+ */
Richard Phibel bd001b
+rpmRC rpmLeadWrite(FD_t fd, struct rpmlead_s l);
Richard Phibel bd001b
 
Richard Phibel bd001b
 /** \ingroup lead
Richard Phibel bd001b
  * Read lead from file handle.
Richard Phibel bd001b
@@ -35,6 +61,15 @@ rpmRC rpmLeadWrite(FD_t fd, Header h);
Richard Phibel bd001b
  */
Richard Phibel bd001b
 rpmRC rpmLeadRead(FD_t fd, char **emsg);
Richard Phibel bd001b
 
Richard Phibel bd001b
+/** \ingroup lead
Richard Phibel bd001b
+ * Read lead from file handle and return it.
Richard Phibel bd001b
+ * @param fd		file handle
Richard Phibel bd001b
+ * @param[out] emsg		failure message on error (malloced)
Richard Phibel bd001b
+ * @param[out] ret		address of lead
Richard Phibel bd001b
+ * @return		RPMRC_OK on success, RPMRC_FAIL/RPMRC_NOTFOUND on error
Richard Phibel bd001b
+ */
Richard Phibel bd001b
+rpmRC rpmLeadReadAndReturn(FD_t fd, char **emsg, struct rpmlead_s * ret);
Richard Phibel bd001b
+
Richard Phibel bd001b
 #ifdef __cplusplus
Richard Phibel bd001b
 }
Richard Phibel bd001b
 #endif
Richard Phibel bd001b
diff --git a/rpm2extents.c b/rpm2extents.c
Richard Phibel bd001b
index 7dd5128decb03781411bd714339b3b6e9b805842..702d3765d76faf618992ca112011d2312d7fcdcc 100644
Richard Phibel bd001b
--- a/rpm2extents.c
Richard Phibel bd001b
+++ b/rpm2extents.c
Richard Phibel bd001b
@@ -134,6 +134,28 @@ exit:
Richard Phibel bd001b
     return rc;
Richard Phibel bd001b
 }
Richard Phibel bd001b
 
Richard Phibel bd001b
+/**
Richard Phibel bd001b
+ * Check if package is in deny list.
Richard Phibel bd001b
+ * @param package_name	package name
Richard Phibel bd001b
+ * @return 		true if package is in deny list
Richard Phibel bd001b
+ */
Richard Phibel bd001b
+static inline int isInDenyList(char * package_name)
Richard Phibel bd001b
+{
Richard Phibel bd001b
+    int is_in_deny_list = 0;
Richard Phibel bd001b
+    if (package_name) {
Richard Phibel bd001b
+	char *e_denylist = getenv("LIBREPO_TRANSCODE_RPMS_DENYLIST");
Richard Phibel bd001b
+	char *denytlist_item = strtok(e_denylist, ",");
Richard Phibel bd001b
+	while (denytlist_item) {
Richard Phibel bd001b
+	    if (strstr(package_name, denytlist_item)) {
Richard Phibel bd001b
+		is_in_deny_list = 1;
Richard Phibel bd001b
+		break;
Richard Phibel bd001b
+	    }
Richard Phibel bd001b
+	    denytlist_item = strtok(NULL, ",");
Richard Phibel bd001b
+	}
Richard Phibel bd001b
+    }
Richard Phibel bd001b
+	return is_in_deny_list;
Richard Phibel bd001b
+}
Richard Phibel bd001b
+
Richard Phibel bd001b
 static rpmRC FDWriteSignaturesValidation(FD_t fdo, int rpmvsrc, char *msg) {
Richard Phibel bd001b
     size_t len;
Richard Phibel bd001b
     rpmRC rc = RPMRC_FAIL;
Richard Phibel bd001b
@@ -239,15 +261,41 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
Richard Phibel bd001b
     uint32_t offset_ix = 0;
Richard Phibel bd001b
     size_t len;
Richard Phibel bd001b
     int next = 0;
Richard Phibel bd001b
+	struct rpmlead_s l;
Richard Phibel bd001b
+    rpmfiles files = NULL;
Richard Phibel bd001b
+    rpmfi fi = NULL;
Richard Phibel bd001b
+    char *msg = NULL;
Richard Phibel bd001b
 
Richard Phibel bd001b
     fdo = fdDup(STDOUT_FILENO);
Richard Phibel bd001b
 
Richard Phibel bd001b
+    rc = rpmLeadReadAndReturn(fdi, &msg, &l);
Richard Phibel bd001b
+    if (rc != RPMRC_OK)
Richard Phibel bd001b
+	goto exit;
Richard Phibel bd001b
+
Richard Phibel bd001b
+    /* Skip conversion if package is in deny list */
Richard Phibel bd001b
+    if (isInDenyList(l.name)) {
Richard Phibel bd001b
+	if (rpmLeadWrite(fdo, l)) {
Richard Phibel bd001b
+		fprintf(stderr, _("Unable to write package lead: %s\n"),
Richard Phibel bd001b
+		Fstrerror(fdo));
Richard Phibel bd001b
+	    rc = RPMRC_FAIL;
Richard Phibel bd001b
+	    goto exit;
Richard Phibel bd001b
+	}
Richard Phibel bd001b
+
Richard Phibel bd001b
+	ssize_t fdilength = ufdCopy(fdi, fdo);
Richard Phibel bd001b
+	if (fdilength == -1) {
Richard Phibel bd001b
+	    fprintf(stderr, _("process_package cat failed\n"));
Richard Phibel bd001b
+	    rc = RPMRC_FAIL;
Richard Phibel bd001b
+	    goto exit;
Richard Phibel bd001b
+	}
Richard Phibel bd001b
+
Richard Phibel bd001b
+	goto exit;
Richard Phibel bd001b
+    } else {
Richard Phibel bd001b
     if (rpmReadPackageRaw(fdi, &sigh, &h)) {
Richard Phibel bd001b
 	rpmlog(RPMLOG_ERR, _("Error reading package\n"));
Richard Phibel bd001b
 	exit(EXIT_FAILURE);
Richard Phibel bd001b
     }
Richard Phibel bd001b
 
Richard Phibel bd001b
-    if (rpmLeadWrite(fdo, h))
Richard Phibel bd001b
+    if (rpmLeadWriteFromHeader(fdo, h))
Richard Phibel bd001b
     {
Richard Phibel bd001b
 	rpmlog(RPMLOG_ERR, _("Unable to write package lead: %s\n"),
Richard Phibel bd001b
 		Fstrerror(fdo));
Richard Phibel bd001b
@@ -264,38 +312,41 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
Richard Phibel bd001b
 	exit(EXIT_FAILURE);
Richard Phibel bd001b
     }
Richard Phibel bd001b
 
Richard Phibel bd001b
-    /* Retrieve payload size and compression type. */
Richard Phibel bd001b
-    {
Richard Phibel bd001b
-	const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
Richard Phibel bd001b
-	rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
Richard Phibel bd001b
-    }
Richard Phibel bd001b
+	/* Retrieve payload size and compression type. */
Richard Phibel bd001b
+	{
Richard Phibel bd001b
+	    const char *compr =
Richard Phibel bd001b
+		headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
Richard Phibel bd001b
+	    rpmio_flags =
Richard Phibel bd001b
+		rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
Richard Phibel bd001b
+	}
Richard Phibel bd001b
 
Richard Phibel bd001b
-    gzdi = Fdopen(fdi, rpmio_flags);	/* XXX gzdi == fdi */
Richard Phibel bd001b
-    free(rpmio_flags);
Richard Phibel bd001b
+	gzdi = Fdopen(fdi, rpmio_flags);	/* XXX gzdi == fdi */
Richard Phibel bd001b
+	free(rpmio_flags);
Richard Phibel bd001b
 
Richard Phibel bd001b
     if (gzdi == NULL) {
Richard Phibel bd001b
 	rpmlog(RPMLOG_ERR, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
Richard Phibel bd001b
 	exit(EXIT_FAILURE);
Richard Phibel bd001b
     }
Richard Phibel bd001b
 
Richard Phibel bd001b
-    rpmfiles files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER);
Richard Phibel bd001b
-    rpmfi fi = rpmfiNewArchiveReader(gzdi, files,
Richard Phibel bd001b
-				     RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST);
Richard Phibel bd001b
+	files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER);
Richard Phibel bd001b
+	fi = rpmfiNewArchiveReader(gzdi, files,
Richard Phibel bd001b
+				   RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST);
Richard Phibel bd001b
 
Richard Phibel bd001b
-    /* this is encoded in the file format, so needs to be fixed size (for
Richard Phibel bd001b
-     * now?)
Richard Phibel bd001b
-     */
Richard Phibel bd001b
-    diglen = (uint32_t)rpmDigestLength(rpmfiDigestAlgo(fi));
Richard Phibel bd001b
-    digestSet ds = digestSetCreate(rpmfiFC(fi), digestSetHash, digestSetCmp,
Richard Phibel bd001b
-				   NULL);
Richard Phibel bd001b
-    struct digestoffset offsets[rpmfiFC(fi)];
Richard Phibel bd001b
-    pos = RPMLEAD_SIZE + headerSizeof(sigh, HEADER_MAGIC_YES);
Richard Phibel bd001b
+	/* this is encoded in the file format, so needs to be fixed size (for
Richard Phibel bd001b
+	 * now?)
Richard Phibel bd001b
+	 */
Richard Phibel bd001b
+	diglen = (uint32_t) rpmDigestLength(rpmfiDigestAlgo(fi));
Richard Phibel bd001b
+	digestSet ds =
Richard Phibel bd001b
+	    digestSetCreate(rpmfiFC(fi), digestSetHash, digestSetCmp,
Richard Phibel bd001b
+			    NULL);
Richard Phibel bd001b
+	struct digestoffset offsets[rpmfiFC(fi)];
Richard Phibel bd001b
+	pos = RPMLEAD_SIZE + headerSizeof(sigh, HEADER_MAGIC_YES);
Richard Phibel bd001b
 
Richard Phibel bd001b
-    /* main headers are aligned to 8 byte boundry */
Richard Phibel bd001b
-    pos += pad_to(pos, 8);
Richard Phibel bd001b
-    pos += headerSizeof(h, HEADER_MAGIC_YES);
Richard Phibel bd001b
+	/* main headers are aligned to 8 byte boundry */
Richard Phibel bd001b
+	pos += pad_to(pos, 8);
Richard Phibel bd001b
+	pos += headerSizeof(h, HEADER_MAGIC_YES);
Richard Phibel bd001b
 
Richard Phibel bd001b
-    zeros = xcalloc(fundamental_block_size, 1);
Richard Phibel bd001b
+	zeros = xcalloc(fundamental_block_size, 1);
Richard Phibel bd001b
 
Richard Phibel bd001b
     while (next >= 0) {
Richard Phibel bd001b
 	next = rpmfiNext(fi);
Richard Phibel bd001b
@@ -342,8 +393,8 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
Richard Phibel bd001b
     }
Richard Phibel bd001b
     Fclose(gzdi);	/* XXX gzdi == fdi */
Richard Phibel bd001b
 
Richard Phibel bd001b
-    qsort(offsets, (size_t)offset_ix, sizeof(struct digestoffset),
Richard Phibel bd001b
-	  digestoffsetCmp);
Richard Phibel bd001b
+	qsort(offsets, (size_t) offset_ix, sizeof(struct digestoffset),
Richard Phibel bd001b
+	      digestoffsetCmp);
Richard Phibel bd001b
 
Richard Phibel bd001b
     validation_pos = pos;
Richard Phibel bd001b
     ssize_t validation_len = ufdCopy(validationi, fdo);
Richard Phibel bd001b
@@ -412,6 +463,7 @@ static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)
Richard Phibel bd001b
 	rc = RPMRC_FAIL;
Richard Phibel bd001b
 	goto exit;
Richard Phibel bd001b
     }
Richard Phibel bd001b
+	}
Richard Phibel bd001b
 
Richard Phibel bd001b
 exit:
Richard Phibel bd001b
     rpmfilesFree(files);
Richard Phibel bd001b
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
Richard Phibel bd001b
index b4897f1de444080c8dc6c4913b5f33de20796822..d54e254ff41a0441d04fbcf27f26e4809f563b79 100644
Richard Phibel bd001b
--- a/sign/rpmgensig.c
Richard Phibel bd001b
+++ b/sign/rpmgensig.c
Richard Phibel bd001b
@@ -672,7 +672,7 @@ static int rpmSign(const char *rpm, int deleting, int flags)
Richard Phibel bd001b
 	}
Richard Phibel bd001b
 
Richard Phibel bd001b
 	/* Write the lead/signature of the output rpm */
Richard Phibel bd001b
-	rc = rpmLeadWrite(ofd, h);
Richard Phibel bd001b
+	rc = rpmLeadWriteFromHeader(ofd, h);
Richard Phibel bd001b
 	if (rc != RPMRC_OK) {
Richard Phibel bd001b
 	    rpmlog(RPMLOG_ERR, _("%s: writeLead failed: %s\n"), trpm,
Richard Phibel bd001b
 		Fstrerror(ofd));
Richard Phibel bd001b
diff --git a/tests/rpm2extents.at b/tests/rpm2extents.at
Richard Phibel bd001b
index 5135c9cf83d9e75e9d9bc0b84186ab10cc0cbcac..c9c79c5acd22b86704460f295712ce7ab5ee3259 100644
Richard Phibel bd001b
--- a/tests/rpm2extents.at
Richard Phibel bd001b
+++ b/tests/rpm2extents.at
Richard Phibel bd001b
@@ -95,6 +95,17 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64-signed.rpm; echo $?
Richard Phibel bd001b
 [])
Richard Phibel bd001b
 AT_CLEANUP
Richard Phibel bd001b
 
Richard Phibel bd001b
+# check that package in denylist is not transcoded
Richard Phibel bd001b
+AT_SETUP([rpm2extents denylist])
Richard Phibel bd001b
+AT_KEYWORDS([rpm2extents])
Richard Phibel bd001b
+AT_CHECK([
Richard Phibel bd001b
+export LIBREPO_TRANSCODE_RPMS_DENYLIST="vim,hello,cowsay"
Richard Phibel bd001b
+runroot_other cat /data/RPMS/hello-2.0-1.x86_64.rpm | runroot_other rpm2extents SHA256 | runroot_other cmp /data/RPMS/hello-2.0-1.x86_64.rpm -],
Richard Phibel bd001b
+[0],
Richard Phibel bd001b
+[],
Richard Phibel bd001b
+[ignore])
Richard Phibel bd001b
+AT_CLEANUP
Richard Phibel bd001b
+
Richard Phibel bd001b
 AT_SETUP([rpm2extents install package])
Richard Phibel bd001b
 AT_KEYWORDS([rpm2extents reflink])
Richard Phibel bd001b
 AT_SKIP_IF([$REFLINK_DISABLED])