summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2016-11-22 09:54:27 +0200
committerPanu Matilainen <pmatilai@redhat.com>2016-11-22 10:19:24 +0200
commit91d2d70c3b4ec53911f97395fcacffca0d0ce2c2 (patch)
tree594a76e4d512dda5893db0a138c9ad53b1773593
parent10429a37e018811a59f979872902a37377c7f744 (diff)
downloadrpm-91d2d70c3b4ec53911f97395fcacffca0d0ce2c2.tar.gz
Consolidate signature + header read to new hdrblobRead() function
The signature and package header reading only differ by a few minor bits like number of tags allowed, doing this in copy-slop code is just dumb. There's an ugly little quirk here in that headerImport() can in theory still fail even if hdrblobRead() succeeds and we need to manually clean up in that case. But that can be addressed in a later commit...
-rw-r--r--lib/header.c65
-rw-r--r--lib/header_internal.h6
-rw-r--r--lib/package.c44
-rw-r--r--lib/signature.c44
4 files changed, 74 insertions, 85 deletions
diff --git a/lib/header.c b/lib/header.c
index 34d42e036..aa73327ce 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -1892,6 +1892,71 @@ exit:
return rc;
}
+rpmRC hdrblobRead(FD_t fd, rpmTagVal regionTag, hdrblob blob, char **emsg)
+{
+ int32_t block[4];
+ int32_t il;
+ int32_t dl;
+ int32_t * ei = NULL;
+ size_t uc;
+ size_t nb;
+ rpmRC rc = RPMRC_FAIL; /* assume failure */
+ int xx;
+ int32_t il_max = HEADER_TAGS_MAX;
+ int32_t dl_max = HEADER_DATA_MAX;
+
+ if (regionTag == RPMTAG_HEADERSIGNATURES) {
+ il_max = 32;
+ dl_max = 8192;
+ }
+
+ memset(block, 0, sizeof(block));
+ if ((xx = Freadall(fd, block, sizeof(block))) != sizeof(block)) {
+ rasprintf(emsg,
+ _("hdr size(%d): BAD, read returned %d"), (int)sizeof(block), xx);
+ goto exit;
+ }
+ if (memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) {
+ rasprintf(emsg, _("hdr magic: BAD"));
+ goto exit;
+ }
+ il = ntohl(block[2]);
+ if (hdrchkRange(il_max, il)) {
+ rasprintf(emsg, _("hdr tags: BAD, no. of tags(%d) out of range"), il);
+ goto exit;
+ }
+ dl = ntohl(block[3]);
+ if (hdrchkRange(dl_max, dl)) {
+ rasprintf(emsg, _("hdr data: BAD, no. of bytes(%d) out of range"), dl);
+ goto exit;
+ }
+
+ nb = (il * sizeof(struct entryInfo_s)) + dl;
+ uc = sizeof(il) + sizeof(dl) + nb;
+ ei = xmalloc(uc);
+ ei[0] = block[2];
+ ei[1] = block[3];
+ if ((xx = Freadall(fd, (char *)&ei[2], nb)) != nb) {
+ rasprintf(emsg, _("hdr blob(%zd): BAD, read returned %d"), nb, xx);
+ goto exit;
+ }
+
+ rc = hdrblobInit(ei, uc, regionTag, 1, blob, emsg);
+
+exit:
+ if (rc != RPMRC_OK) {
+ free(ei);
+ if (emsg && *emsg && regionTag == RPMTAG_HEADERSIGNATURES) {
+ /* rstrscat() cannot handle overlap even if it claims so */
+ char *tmp = rstrscat(NULL, _("signature "), *emsg, NULL);
+ free(*emsg);
+ *emsg = tmp;
+ }
+ }
+
+ return rc;
+}
+
rpmRC hdrblobInit(const void *uh, size_t uc,
rpmTagVal regionTag, int exact_size,
struct hdrblob_s *blob, char **emsg)
diff --git a/lib/header_internal.h b/lib/header_internal.h
index c59064bee..d84c520c4 100644
--- a/lib/header_internal.h
+++ b/lib/header_internal.h
@@ -42,7 +42,8 @@ struct hdrblob_s {
* Sanity check on no. of tags.
* This check imposes a limit of 65K tags, more than enough.
*/
-#define hdrchkTags(_ntags) ((_ntags) & 0xffff0000)
+#define HEADER_TAGS_MAX 0x0000ffff
+#define hdrchkTags(_ntags) ((_ntags) & (~HEADER_TAGS_MAX))
/**
* Sanity check on type values.
@@ -85,6 +86,9 @@ rpmRC hdrblobInit(const void *uh, size_t uc,
rpmTagVal regionTag, int exact_size,
struct hdrblob_s *blob, char **emsg);
+RPM_GNUC_INTERNAL
+rpmRC hdrblobRead(FD_t fd, rpmTagVal regionTag, hdrblob blob, char **emsg);
+
/** \ingroup header
* Set header instance (rpmdb record number)
* @param h header
diff --git a/lib/package.c b/lib/package.c
index b97752dbe..5cf928af7 100644
--- a/lib/package.c
+++ b/lib/package.c
@@ -256,71 +256,31 @@ static rpmRC rpmpkgReadHeader(rpmKeyring keyring, rpmVSFlags vsflags,
FD_t fd, Header *hdrp, char ** msg)
{
char *buf = NULL;
- int32_t block[4];
- int32_t il;
- int32_t dl;
- int32_t * ei = NULL;
- size_t uc;
- size_t nb;
struct hdrblob_s blob;
Header h = NULL;
rpmRC rc = RPMRC_FAIL; /* assume failure */
- int xx;
if (hdrp)
*hdrp = NULL;
if (msg)
*msg = NULL;
- memset(block, 0, sizeof(block));
- if ((xx = Freadall(fd, block, sizeof(block))) != sizeof(block)) {
- rasprintf(&buf,
- _("hdr size(%d): BAD, read returned %d"), (int)sizeof(block), xx);
- goto exit;
- }
- if (memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) {
- rasprintf(&buf, _("hdr magic: BAD"));
- goto exit;
- }
- il = ntohl(block[2]);
- if (hdrchkTags(il)) {
- rasprintf(&buf, _("hdr tags: BAD, no. of tags(%d) out of range"), il);
- goto exit;
- }
- dl = ntohl(block[3]);
- if (hdrchkData(dl)) {
- rasprintf(&buf,
- _("hdr data: BAD, no. of bytes(%d) out of range"), dl);
- goto exit;
- }
-
- nb = (il * sizeof(struct entryInfo_s)) + dl;
- uc = sizeof(il) + sizeof(dl) + nb;
- ei = xmalloc(uc);
- ei[0] = block[2];
- ei[1] = block[3];
- if ((xx = Freadall(fd, (char *)&ei[2], nb)) != nb) {
- rasprintf(&buf, _("hdr blob(%zd): BAD, read returned %d"), nb, xx);
- goto exit;
- }
-
- if (hdrblobInit(ei, uc, RPMTAG_HEADERIMMUTABLE, 1, &blob, &buf) != RPMRC_OK)
+ if (hdrblobRead(fd, RPMTAG_HEADERIMMUTABLE, &blob, &buf) != RPMRC_OK)
goto exit;
/* OK, blob looks sane, load the header. */
h = headerImport(blob.ei, blob.uc, 0);
if (h == NULL) {
+ free(blob.ei);
free(buf);
rasprintf(&buf, _("hdr load: BAD"));
goto exit;
}
- ei = NULL; /* XXX will be freed with header */
rc = RPMRC_OK;
exit:
if (hdrp && h && rc == RPMRC_OK)
*hdrp = headerLink(h);
- free(ei);
headerFree(h);
if (msg != NULL && *msg == NULL && buf != NULL) {
diff --git a/lib/signature.c b/lib/signature.c
index 7a1dcda50..6a9b63468 100644
--- a/lib/signature.c
+++ b/lib/signature.c
@@ -151,62 +151,23 @@ rpmRC rpmReadSignature(FD_t fd, Header * sighp, char ** msg)
{
char *buf = NULL;
int32_t block[4];
- int32_t il;
- int32_t dl;
- int32_t * ei = NULL;
- unsigned int nb, uc;
struct hdrblob_s blob;
Header sigh = NULL;
rpmRC rc = RPMRC_FAIL; /* assume failure */
- int xx;
if (sighp)
*sighp = NULL;
- memset(block, 0, sizeof(block));
- if ((xx = Freadall(fd, block, sizeof(block))) != sizeof(block)) {
- rasprintf(&buf, _("sigh size(%d): BAD, read returned %d"),
- (int)sizeof(block), xx);
- goto exit;
- }
- if (memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) {
- rasprintf(&buf, _("sigh magic: BAD"));
- goto exit;
- }
- il = ntohl(block[2]);
- if (il < 0 || il > 32) {
- rasprintf(&buf,
- _("sigh tags: BAD, no. of tags(%d) out of range"), il);
- goto exit;
- }
- dl = ntohl(block[3]);
- if (dl < 0 || dl > 8192) {
- rasprintf(&buf,
- _("sigh data: BAD, no. of bytes(%d) out of range"), dl);
- goto exit;
- }
-
- nb = (il * sizeof(struct entryInfo_s)) + dl;
- uc = sizeof(il) + sizeof(dl) + nb;
- ei = xmalloc(uc);
- ei[0] = block[2];
- ei[1] = block[3];
- if ((xx = Freadall(fd, &ei[2], nb)) != nb) {
- rasprintf(&buf,
- _("sigh blob(%d): BAD, read returned %d"), (int)nb, xx);
- goto exit;
- }
-
- if (hdrblobInit(ei, uc, RPMTAG_HEADERSIGNATURES, 1, &blob, &buf) != RPMRC_OK)
+ if (hdrblobRead(fd, RPMTAG_HEADERSIGNATURES, &blob, &buf) != RPMRC_OK)
goto exit;
/* OK, blob looks sane, load the header. */
sigh = headerImport(blob.ei, blob.uc, 0);
if (sigh == NULL) {
rasprintf(&buf, _("sigh load: BAD"));
+ free(blob.ei);
goto exit;
}
- ei = NULL; /* XXX will be freed with header */
{ size_t sigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
size_t pad = (8 - (sigSize % 8)) % 8; /* 8-byte pad */
@@ -242,7 +203,6 @@ exit:
if (sighp && sigh && rc == RPMRC_OK)
*sighp = headerLink(sigh);
headerFree(sigh);
- free(ei);
if (msg != NULL) {
*msg = buf;