diff options
author | Michael Schroeder <mls@suse.de> | 2018-01-05 13:33:32 +0100 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2018-03-28 14:09:16 +0300 |
commit | b7c79df52de1d4cac5d9168d6c88c440eb051b96 (patch) | |
tree | a8c8e49604d6b3c98dc4f89f1f6e917c937be9b7 | |
parent | d765baf3f0f9f237ca107cc9d733d40984fe30e3 (diff) | |
download | rpm-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.c | 41 |
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) |