|
|
5523e9 |
Adjusted lib/package.c section to apply, and 4.11.x requires the
|
|
|
5523e9 |
same change in lib/signature.c as well.
|
|
|
5523e9 |
|
|
|
5523e9 |
From 89dce2b91d7d73a1e225461a7392c3d6d7a30a95 Mon Sep 17 00:00:00 2001
|
|
|
5523e9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
5523e9 |
Date: Wed, 19 Oct 2016 14:48:08 +0300
|
|
|
5523e9 |
Subject: [PATCH] Verify data is within range and does not overlap in
|
|
|
5523e9 |
headerVerifyInfo()
|
|
|
5523e9 |
|
|
|
5523e9 |
Checking whether data start offset is within header data area is of no use
|
|
|
5523e9 |
whatsoever if the entire chunk doesn't fit. Validate the entire data
|
|
|
5523e9 |
fits within range and that it does not overlap, however with string
|
|
|
5523e9 |
types we can only check the array size is sane but we cant check the
|
|
|
5523e9 |
actual content.
|
|
|
5523e9 |
|
|
|
5523e9 |
Adjust the upper limit for region trailer in headerVerifyRegion() so
|
|
|
5523e9 |
it fits the new rules, but in reality calling headerVerifyInfo() for
|
|
|
5523e9 |
the region tags is rather pointless since they're so different.
|
|
|
5523e9 |
|
|
|
5523e9 |
Partial fix for RhBug:1373107.
|
|
|
5523e9 |
---
|
|
|
5523e9 |
lib/header.c | 21 ++++++++++++++++-----
|
|
|
5523e9 |
lib/package.c | 2 +-
|
|
|
5523e9 |
2 files changed, 17 insertions(+), 6 deletions(-)
|
|
|
5523e9 |
|
|
|
5523e9 |
diff --git a/lib/header.c b/lib/header.c
|
|
|
5523e9 |
index 7f7c115..cac5c94 100644
|
|
|
5523e9 |
--- a/lib/header.c
|
|
|
5523e9 |
+++ b/lib/header.c
|
|
|
5523e9 |
@@ -196,7 +196,8 @@ int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate)
|
|
|
5523e9 |
{
|
|
|
5523e9 |
entryInfo pe = (entryInfo) pev;
|
|
|
5523e9 |
entryInfo info = iv;
|
|
|
5523e9 |
- int i;
|
|
|
5523e9 |
+ int i, tsize;
|
|
|
5523e9 |
+ int32_t end = 0;
|
|
|
5523e9 |
|
|
|
5523e9 |
for (i = 0; i < il; i++) {
|
|
|
5523e9 |
info->tag = ntohl(pe[i].tag);
|
|
|
5523e9 |
@@ -206,16 +207,26 @@ int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate)
|
|
|
5523e9 |
info->offset = -info->offset;
|
|
|
5523e9 |
info->count = ntohl(pe[i].count);
|
|
|
5523e9 |
|
|
|
5523e9 |
+ /* Previous data must not overlap */
|
|
|
5523e9 |
+ if (end > info->offset)
|
|
|
5523e9 |
+ return i;
|
|
|
5523e9 |
+
|
|
|
5523e9 |
if (hdrchkType(info->type))
|
|
|
5523e9 |
return i;
|
|
|
5523e9 |
if (hdrchkAlign(info->type, info->offset))
|
|
|
5523e9 |
return i;
|
|
|
5523e9 |
- if (hdrchkRange(dl, info->offset))
|
|
|
5523e9 |
- return i;
|
|
|
5523e9 |
- if (hdrchkData(info->count))
|
|
|
5523e9 |
- return i;
|
|
|
5523e9 |
|
|
|
5523e9 |
+ /* For string types we can only check the array size is sane */
|
|
|
5523e9 |
+ tsize = typeSizes[info->type];
|
|
|
5523e9 |
+ if (tsize < 1)
|
|
|
5523e9 |
+ tsize = 1;
|
|
|
5523e9 |
+
|
|
|
5523e9 |
+ /* Verify the data actually fits */
|
|
|
5523e9 |
+ end = info->offset + (info->count * tsize);
|
|
|
5523e9 |
+ if (hdrchkRange(dl, end))
|
|
|
5523e9 |
+ return i;
|
|
|
5523e9 |
}
|
|
|
5523e9 |
+
|
|
|
5523e9 |
return -1;
|
|
|
5523e9 |
}
|
|
|
5523e9 |
|
|
|
5523e9 |
diff --git a/lib/package.c b/lib/package.c
|
|
|
5523e9 |
index b6bea09..bb83163 100644
|
|
|
5523e9 |
--- a/lib/package.c
|
|
|
5523e9 |
+++ b/lib/package.c
|
|
|
5523e9 |
@@ -339,7 +339,7 @@ static rpmRC headerVerify(rpmKeyring keyring, rpmVSFlags vsflags,
|
|
|
5523e9 |
(void) memcpy(&info, regionEnd, REGION_TAG_COUNT);
|
|
|
5523e9 |
regionEnd += REGION_TAG_COUNT;
|
|
|
5523e9 |
|
|
|
5523e9 |
- if (headerVerifyInfo(1, il * sizeof(*pe), &info, &entry.info, 1) != -1 ||
|
|
|
5523e9 |
+ if (headerVerifyInfo(1, il * sizeof(*pe) + REGION_TAG_COUNT, &info, &entry.info, 1) != -1 ||
|
|
|
5523e9 |
!(entry.info.tag == RPMTAG_HEADERIMMUTABLE
|
|
|
5523e9 |
&& entry.info.type == REGION_TAG_TYPE
|
|
|
5523e9 |
&& entry.info.count == REGION_TAG_COUNT))
|
|
|
5523e9 |
diff --git a/lib/signature.c b/lib/signature.c
|
|
|
5523e9 |
index d8017dc..ddf2eb8 100644
|
|
|
5523e9 |
--- a/lib/signature.c
|
|
|
5523e9 |
+++ b/lib/signature.c
|
|
|
5523e9 |
@@ -165,7 +165,7 @@ rpmRC rpmReadSignature(FD_t fd, Header * sighp, sigType sig_type, char ** msg)
|
|
|
5523e9 |
}
|
|
|
5523e9 |
dataEnd += REGION_TAG_COUNT;
|
|
|
5523e9 |
|
|
|
5523e9 |
- xx = headerVerifyInfo(1, il * sizeof(*pe), &info, &entry.info, 1);
|
|
|
5523e9 |
+ xx = headerVerifyInfo(1, il * sizeof(*pe) + REGION_TAG_COUNT, &info, &entry.info, 1);
|
|
|
5523e9 |
if (xx != -1 ||
|
|
|
5523e9 |
!((entry.info.tag == RPMTAG_HEADERSIGNATURES || entry.info.tag == RPMTAG_HEADERIMAGE)
|
|
|
5523e9 |
&& entry.info.type == REGION_TAG_TYPE
|