From 52bcafcfb2e7c6bb8bb59f8def831e4f6a6f4930 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 30 Nov 2011 09:12:48 +0200 Subject: [PATCH] Add an enhanced interface for loading, aka importing, headers - Unlike headerLoad(), headerImport() takes a blob size argument to allow sanity checking the size calculated from the blob itself against the "physical" passed-in blob size so its a bit safer. Note that header size is capped by various things - its not size_t. - headerImport() also takes a flags argument to allow controlling various aspects of importing. - Implement "take copy of blob" as a flag to headerImport(), push the copying into headerCreate() where we already know the blob size, avoiding the need to do double-calculations on headerCopyLoad().. - headerLoad() and headerCopyLoad() are now just compat wrappers around the new interface. --- lib/header.c | 46 ++++++++++++++++++++++------------------------ lib/header.h | 17 +++++++++++++++++ 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/lib/header.c b/lib/header.c index 6458f41..9ebf592 100644 --- a/lib/header.c +++ b/lib/header.c @@ -154,11 +154,11 @@ Header headerFree(Header h) return NULL; } -static Header headerCreate(void *blob, int32_t indexLen) +static Header headerCreate(void *blob, unsigned int pvlen, int32_t indexLen) { Header h = xcalloc(1, sizeof(*h)); - h->blob = blob; if (blob) { + h->blob = (pvlen > 0) ? memcpy(xmalloc(pvlen), blob, pvlen) : blob; h->indexAlloced = indexLen + 1; h->indexUsed = indexLen; } else { @@ -178,7 +178,7 @@ static Header headerCreate(void *blob, int32_t indexLen) Header headerNew(void) { - return headerCreate(NULL, 0); + return headerCreate(NULL, 0, 0); } int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate) @@ -766,13 +766,13 @@ int headerDel(Header h, rpmTagVal tag) return 0; } -Header headerLoad(void * uh) +Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags) { - int32_t * ei = (int32_t *) uh; + const int32_t * ei = (int32_t *) blob; int32_t il = ntohl(ei[0]); /* index length */ int32_t dl = ntohl(ei[1]); /* data length */ - size_t pvlen = sizeof(il) + sizeof(dl) + - (il * sizeof(struct entryInfo_s)) + dl; + unsigned int pvlen = sizeof(il) + sizeof(dl) + + (il * sizeof(struct entryInfo_s)) + dl;; Header h = NULL; entryInfo pe; unsigned char * dataStart; @@ -781,15 +781,18 @@ Header headerLoad(void * uh) int rdlen; /* Sanity checks on header intro. */ - if (hdrchkTags(il) || hdrchkData(dl)) + if (bsize && bsize != pvlen) goto errxit; + if (hdrchkTags(il) || hdrchkData(dl) || pvlen >= headerMaxbytes) + goto errxit; + + h = headerCreate(blob, (flags & HEADERIMPORT_COPY) ? pvlen : 0, il); + ei = h->blob; /* In case we had to copy */ pe = (entryInfo) &ei[2]; dataStart = (unsigned char *) (pe + il); dataEnd = dataStart + dl; - h = headerCreate(uh, il); - entry = h->index; if (!(htonl(pe->tag) < RPMTAG_HEADERI18NTABLE)) { h->flags |= HEADERFLAG_LEGACY; @@ -894,6 +897,8 @@ Header headerLoad(void * uh) errxit: if (h) { + if (flags & HEADERIMPORT_COPY) + free(h->blob); free(h->index); free(h); } @@ -920,22 +925,15 @@ Header headerReload(Header h, rpmTagVal tag) return nh; } -Header headerCopyLoad(const void * uh) +Header headerLoad(void * uh) { - int32_t * ei = (int32_t *) uh; - int32_t il = ntohl(ei[0]); /* index length */ - int32_t dl = ntohl(ei[1]); /* data length */ - size_t pvlen = sizeof(il) + sizeof(dl) + - (il * sizeof(struct entryInfo_s)) + dl; - Header h = NULL; + return headerImport(uh, 0, 0); +} - /* Sanity checks on header intro. */ - if (!(hdrchkTags(il) || hdrchkData(dl)) && pvlen < headerMaxbytes) { - void * nuh = memcpy(xmalloc(pvlen), uh, pvlen); - if ((h = headerLoad(nuh)) == NULL) - free(nuh); - } - return h; +Header headerCopyLoad(const void * uh) +{ + /* Discards const but that's ok as we'll take a copy */ + return headerImport((void *)uh, 0, HEADERIMPORT_COPY); } Header headerRead(FD_t fd, int magicp) diff --git a/lib/header.h b/lib/header.h index a9160fc..fdd6c99 100644 --- a/lib/header.h +++ b/lib/header.h @@ -110,6 +110,7 @@ Header headerCopy(Header h); /** \ingroup header * Convert header to in-memory representation. + * @deprecated Use headerImport() instead * @param uh on-disk header blob (i.e. with offsets) * @return header */ @@ -117,11 +118,27 @@ Header headerLoad(void * uh); /** \ingroup header * Make a copy and convert header to in-memory representation. + * @deprecated Use headerImport() instead * @param uh on-disk header blob (i.e. with offsets) * @return header */ Header headerCopyLoad(const void * uh); +enum headerImportFlags_e { + HEADERIMPORT_COPY = (1 << 0), /* Make copy of blob on import? */ +}; + +typedef rpmFlags headerImportFlags; + +/** \ingroup header + * Import header to in-memory representation. + * @param blob on-disk header blob (i.e. with offsets) + * @param bsize on-disk header blob size in bytes (0 if unknown) + * @param flags flags to control operation + * @return header + */ +Header headerImport(void *blob, unsigned int bsize, headerImportFlags flags); + /** \ingroup header * Read (and load) header from file handle. * @param fd file handle -- 2.7.4