summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2016-10-19 14:48:08 +0300
committerPanu Matilainen <pmatilai@redhat.com>2016-11-02 10:41:53 +0200
commit489769fea8ddbe187be92bc5b247c211a3bb065d (patch)
tree49cc0dd2e68f0924d89339518f9987b173d14728
parent648d717f231cccb1ce976d5fa038c9255e7bf6b9 (diff)
downloadrpm-489769fea8ddbe187be92bc5b247c211a3bb065d.tar.gz
Verify data is within range and does not overlap in headerVerifyInfo()
Checking whether data start offset is within header data area is of no use whatsoever if the entire chunk doesn't fit. Validate the entire data fits within range and that it does not overlap, however with string types we can only check the array size is sane but we cant check the actual content. Adjust the upper limit for region trailer in headerVerifyRegion() so it fits the new rules, but in reality calling headerVerifyInfo() for the region tags is rather pointless since they're so different. Partial fix for RhBug:1373107. (cherry picked from commit 89dce2b91d7d73a1e225461a7392c3d6d7a30a95)
-rw-r--r--lib/header.c21
-rw-r--r--lib/package.c2
2 files changed, 17 insertions, 6 deletions
diff --git a/lib/header.c b/lib/header.c
index f78ba788f..3f9d0e70c 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -194,7 +194,8 @@ int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate)
{
entryInfo pe = (entryInfo) pev;
entryInfo info = iv;
- int i;
+ int i, tsize;
+ int32_t end = 0;
for (i = 0; i < il; i++) {
info->tag = ntohl(pe[i].tag);
@@ -204,16 +205,26 @@ int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate)
info->offset = -info->offset;
info->count = ntohl(pe[i].count);
+ /* Previous data must not overlap */
+ if (end > info->offset)
+ return i;
+
if (hdrchkType(info->type))
return i;
if (hdrchkAlign(info->type, info->offset))
return i;
- if (hdrchkRange(dl, info->offset))
- return i;
- if (hdrchkData(info->count))
- return i;
+ /* For string types we can only check the array size is sane */
+ tsize = typeSizes[info->type];
+ if (tsize < 1)
+ tsize = 1;
+
+ /* Verify the data actually fits */
+ end = info->offset + (info->count * tsize);
+ if (hdrchkRange(dl, end))
+ return i;
}
+
return -1;
}
diff --git a/lib/package.c b/lib/package.c
index fb2ff9194..890816a2f 100644
--- a/lib/package.c
+++ b/lib/package.c
@@ -333,7 +333,7 @@ rpmRC headerVerifyRegion(rpmTagVal regionTag,
regionEnd += REGION_TAG_COUNT;
rdl = regionEnd - dataStart;
- if (headerVerifyInfo(1, il * sizeof(*pe), &info, &entry->info, 1) != -1 ||
+ if (headerVerifyInfo(1, il * sizeof(*pe) + REGION_TAG_COUNT, &info, &entry->info, 1) != -1 ||
!(entry->info.tag == regionTag
&& entry->info.type == REGION_TAG_TYPE
&& entry->info.count == REGION_TAG_COUNT))