summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2018-01-05 13:33:32 +0100
committerPanu Matilainen <pmatilai@redhat.com>2018-03-28 14:09:16 +0300
commitb7c79df52de1d4cac5d9168d6c88c440eb051b96 (patch)
treea8c8e49604d6b3c98dc4f89f1f6e917c937be9b7
parentd765baf3f0f9f237ca107cc9d733d40984fe30e3 (diff)
downloadrpm-b7c79df52de1d4cac5d9168d6c88c440eb051b96.tar.gz
Fix sigheader generation for big archives
The old code just subtracted 8 bytes from the reserved space, but that does not take tag alignment into account and led to the signature header overwriting the package header. We now use headerSizeof to calculate the real size difference. (cherry picked from commit a76ca4d569f01e58bb7f0b678b7d50ea0626f11a)
-rw-r--r--lib/signature.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/lib/signature.c b/lib/signature.c
index 41bf85893..9bd6de2af 100644
--- a/lib/signature.c
+++ b/lib/signature.c
@@ -307,6 +307,8 @@ rpmRC rpmGenerateSignature(char *SHA1, uint8_t *MD5, rpm_loff_t size,
char *reservedSpace;
int spaceSize = 32; /* always reserve a bit of space */
int gpgSize = rpmExpandNumeric("%{__gpg_reserved_space}");
+ rpm_off_t size32 = size;
+ rpm_off_t payloadSize32 = payloadSize;
/* Prepare signature */
sig = rpmNewSignature();
@@ -327,21 +329,34 @@ rpmRC rpmGenerateSignature(char *SHA1, uint8_t *MD5, rpm_loff_t size,
rpmtdReset(&td);
td.count = 1;
- if (payloadSize < UINT32_MAX) {
- rpm_off_t p = payloadSize;
- rpm_off_t s = size;
- td.type = RPM_INT32_TYPE;
+ td.type = RPM_INT32_TYPE;
- td.tag = RPMSIGTAG_PAYLOADSIZE;
- td.data = &p;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
+ td.tag = RPMSIGTAG_PAYLOADSIZE;
+ td.data = &payloadSize32;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
- td.tag = RPMSIGTAG_SIZE;
- td.data = &s;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
- } else {
+ td.tag = RPMSIGTAG_SIZE;
+ td.data = &size32;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+
+ if (size >= UINT32_MAX || payloadSize >= UINT32_MAX) {
+ /*
+ * Put the 64bit size variants into the header, but
+ * modify spaceSize so that the resulting header has
+ * the same size. Note that this only works if all tags
+ * with a lower number than RPMSIGTAG_RESERVEDSPACE are
+ * already added and no tag with a higher number is
+ * added yet.
+ */
rpm_loff_t p = payloadSize;
rpm_loff_t s = size;
+ int newsigSize, oldsigSize;
+
+ oldsigSize = headerSizeof(sig, HEADER_MAGIC_YES);
+
+ headerDel(sig, RPMSIGTAG_PAYLOADSIZE);
+ headerDel(sig, RPMSIGTAG_SIZE);
+
td.type = RPM_INT64_TYPE;
td.tag = RPMSIGTAG_LONGARCHIVESIZE;
@@ -352,8 +367,8 @@ rpmRC rpmGenerateSignature(char *SHA1, uint8_t *MD5, rpm_loff_t size,
td.data = &s;
headerPut(sig, &td, HEADERPUT_DEFAULT);
- /* adjust for the size difference between 64- and 32bit tags */
- spaceSize -= 8;
+ newsigSize = headerSizeof(sig, HEADER_MAGIC_YES);
+ spaceSize -= newsigSize - oldsigSize;
}
if (gpgSize > 0)