Verify the entire region trailer, not just its offset, is within data area
authorPanu Matilainen <pmatilai@redhat.com>
Thu, 20 Oct 2011 07:37:31 +0000 (10:37 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Thu, 20 Oct 2011 07:52:58 +0000 (10:52 +0300)
- Offset being within the data area doesn't help if the actual data doesn't
  fit. Since the trailer size is well known, we can just as easily
  make the check accurate to prevent reading beyond end of data in case
  the offset is subtly wrong.
- In headerLoad(), region offset of zero doesn't need sanity checking,
  only validate if its something else and do so accurately there too.

lib/header.c
lib/package.c
lib/signature.c

index ba63de4..e54ef70 100644 (file)
@@ -834,11 +834,11 @@ Header headerLoad(void * uh)
 
        {   int off = ntohl(pe->offset);
 
-           if (hdrchkData(off) || hdrchkRange(dl, off))
-               goto errxit;
            if (off) {
                size_t nb = REGION_TAG_COUNT;
                int32_t stei[nb];
+               if (hdrchkRange(dl, (off + nb)))
+                   goto errxit;
                /* XXX Hmm, why the copy? */
                memcpy(&stei, dataStart + off, nb);
                rdl = -ntohl(stei[2]);  /* negative offset */
index 20b45ff..d70d2d3 100644 (file)
@@ -322,8 +322,8 @@ static rpmRC headerVerify(rpmKeyring keyring, rpmVSFlags vsflags,
        goto exit;
     }
 
-    /* Is the offset within the data area? */
-    if (entry.info.offset >= dl) {
+    /* Is the trailer within the data area? */
+    if (entry.info.offset + REGION_TAG_COUNT > dl) {
        rasprintf(&buf, 
                _("region offset: BAD, tag %d type %d offset %d count %d\n"),
                entry.info.tag, entry.info.type,
index 695b09d..98fabcc 100644 (file)
@@ -138,7 +138,8 @@ rpmRC rpmReadSignature(FD_t fd, Header * sighp, sigType sig_type, char ** msg)
        && entry.info.count == REGION_TAG_COUNT)
     {
 
-       if (entry.info.offset >= dl) {
+       /* Is the trailer within the data area? */
+       if (entry.info.offset + REGION_TAG_COUNT > dl) {
            rasprintf(&buf, 
                _("region offset: BAD, tag %d type %d offset %d count %d\n"),
                entry.info.tag, entry.info.type,