RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: [email protected] Module: rpm Date: 18-May-2009 04:12:40 Branch: HEAD Handle: 2009051802124000 Modified files: rpm/rpmdb header.c header_internal.h Log: - make rpmdb headers readonly with PROT_READ. Summary: Revision Changes Path 1.182 +59 -13 rpm/rpmdb/header.c 1.53 +1 -0 rpm/rpmdb/header_internal.h ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/rpmdb/header.c ============================================================================ $ cvs diff -u -r1.181 -r1.182 header.c --- rpm/rpmdb/header.c 17 May 2009 21:31:39 -0000 1.181 +++ rpm/rpmdb/header.c 18 May 2009 02:12:40 -0000 1.182 @@ -109,14 +109,23 @@ Header h = _h; if (h->index != NULL) { + int mask = (HEADERFLAG_ALLOCATED | HEADERFLAG_MAPPED); indexEntry entry = h->index; size_t i; for (i = 0; i < h->indexUsed; i++, entry++) { - if ((h->flags & HEADERFLAG_ALLOCATED) && ENTRY_IS_REGION(entry)) { + if ((h->flags & mask) && ENTRY_IS_REGION(entry)) { if (entry->length > 0) { rpmuint32_t * ei = entry->data; if ((ei - 2) == h->blob) { - h->blob = _free(h->blob); + if (h->flags & HEADERFLAG_MAPPED) { + if (munmap(h->blob, h->bloblen) != 0) + fprintf(stderr, + "==> munmap(%p[%u]) error(%d): %s\n", + h->blob, h->bloblen, + errno, strerror(errno)); + h->blob = NULL; + } else + h->blob = _free(h->blob); h->bloblen = 0; } entry->data = NULL; @@ -125,6 +134,7 @@ entry->data = _free(entry->data); } entry->data = NULL; + entry->length = 0; } h->index = _free(h->index); } @@ -1039,7 +1049,7 @@ } /*...@-assignexpose -kepttr...@*/ h->blob = uh; - h->bloblen = 0; + h->bloblen = pvlen; /*...@=assignexpose =kepttr...@*/ h->indexAlloced = il + 1; h->indexUsed = il; @@ -1361,27 +1371,63 @@ return nh; } -Header headerCopyLoad(const void * uh) +static Header headerMap(const void * uh, int map) + /*...@*/ { rpmuint32_t * ei = (rpmuint32_t *) uh; - rpmuint32_t il = (rpmuint32_t) ntohl(ei[0]); /* index length */ - rpmuint32_t dl = (rpmuint32_t) ntohl(ei[1]); /* data length */ + rpmuint32_t il = (rpmuint32_t) ntohl(ei[0]); /* index length */ + rpmuint32_t dl = (rpmuint32_t) ntohl(ei[1]); /* data length */ /*...@-sizeoftype@*/ size_t pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo_s)) + dl; /*...@=sizeoftype@*/ void * nuh = NULL; - Header h = NULL; + Header nh = NULL; /* Sanity checks on header intro. */ - if (!(hdrchkTags(il) || hdrchkData(dl)) && pvlen < headerMaxbytes) { + if (hdrchkTags(il) || hdrchkData(dl) || pvlen >= headerMaxbytes) + return NULL; + + if (map) { + static const int prot = PROT_READ | PROT_WRITE; + static const int flags = MAP_PRIVATE| MAP_ANONYMOUS; + static const int fdno = -1; + static const off_t off = 0; + nuh = mmap(NULL, pvlen, prot, flags, fdno, off); + if (nuh == NULL || nuh == (void *)-1) + fprintf(stderr, + "==> mmap(%p[%u], 0x%x, 0x%x, %d, 0x%x) error(%d): %s\n", + NULL, pvlen, prot, flags, fdno, (unsigned)off, + errno, strerror(errno)); + memcpy(nuh, uh, pvlen); + if ((nh = headerLoad(nuh)) != NULL) { +assert(nh->bloblen == pvlen); + nh->flags |= HEADERFLAG_MAPPED; + if (mprotect(nh->blob, nh->bloblen, PROT_READ) != 0) + fprintf(stderr, "==> mprotect(%p[%u],0x%x) error(%d): %s\n", + nh->blob, nh->bloblen, PROT_READ, + errno, strerror(errno)); + nh->flags |= HEADERFLAG_RDONLY; + } else { + if (munmap(nuh, pvlen) != 0) + fprintf(stderr, "==> munmap(%p[%u]) error(%d): %s\n", + nuh, pvlen, errno, strerror(errno)); + } + } else { nuh = memcpy(xmalloc(pvlen), uh, pvlen); - if ((h = headerLoad(nuh)) != NULL) - h->flags |= HEADERFLAG_ALLOCATED; + if ((nh = headerLoad(nuh)) != NULL) + nh->flags |= HEADERFLAG_ALLOCATED; + else + nuh = _free(nuh); } - if (h == NULL) - nuh = _free(nuh); - return h; + + return nh; +} + +Header headerCopyLoad(const void * uh) +{ + static const int map = 1; + return headerMap(uh, map); } int headerIsEntry(Header h, rpmTag tag) @@ . patch -p0 <<'@@ .' Index: rpm/rpmdb/header_internal.h ============================================================================ $ cvs diff -u -r1.52 -r1.53 header_internal.h --- rpm/rpmdb/header_internal.h 17 May 2009 21:31:39 -0000 1.52 +++ rpm/rpmdb/header_internal.h 18 May 2009 02:12:40 -0000 1.53 @@ -113,6 +113,7 @@ #define HEADERFLAG_DEBUG (1 << 3) /*!< Debug this header? */ #define HEADERFLAG_SIGNATURE (1 << 4) /*!< Signature header? */ #define HEADERFLAG_MAPPED (1 << 5) /*!< Is 1st header region mmap'd? */ +#define HEADERFLAG_RDONLY (1 << 6) /*!< Is 1st header region rdonly? */ #if defined(__LCLINT__) /*...@refs@*/ int nrefs; /*!< (unused) keep splint happy */ @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository [email protected]
