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]

Reply via email to