Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPM 4.15.1.1 #1587

Merged
merged 20 commits into from Mar 22, 2021
Merged
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Prev Previous commit
Next Next commit
hdrblobInit() needs bounds checks too
Users can pass untrusted data to hdrblobInit() and it must be robust
against this.

Backported from commit 8f4b3c3
  • Loading branch information
DemiMarie authored and pmatilai committed Mar 22, 2021
commit 9646711891df851dfbf7ef54cc171574a0914b15
48 changes: 31 additions & 17 deletions lib/header.c
Expand Up @@ -11,6 +11,7 @@
#include "system.h"
#include <netdb.h>
#include <errno.h>
#include <inttypes.h>
#include <rpm/rpmtypes.h>
#include <rpm/rpmstring.h>
#include "lib/header_internal.h"
Expand Down Expand Up @@ -1910,6 +1911,25 @@ hdrblob hdrblobFree(hdrblob blob)
return NULL;
}

static rpmRC hdrblobVerifyLengths(rpmTagVal regionTag, uint32_t il, uint32_t dl,
char **emsg) {
uint32_t il_max = HEADER_TAGS_MAX;
uint32_t dl_max = HEADER_DATA_MAX;
if (regionTag == RPMTAG_HEADERSIGNATURES) {
il_max = 32;
dl_max = 64 * 1024 * 1024;
}
if (hdrchkRange(il_max, il)) {
rasprintf(emsg, _("hdr tags: BAD, no. of tags(%" PRIu32 ") out of range"), il);
return RPMRC_FAIL;
}
if (hdrchkRange(dl_max, dl)) {
rasprintf(emsg, _("hdr data: BAD, no. of bytes(%" PRIu32 ") out of range"), dl);
return RPMRC_FAIL;
}
return RPMRC_OK;
}

rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrblob blob, char **emsg)
{
int32_t block[4];
Expand All @@ -1922,13 +1942,6 @@ rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrbl
size_t nb;
rpmRC rc = RPMRC_FAIL; /* assume failure */
int xx;
int32_t il_max = HEADER_TAGS_MAX;
int32_t dl_max = HEADER_DATA_MAX;

if (regionTag == RPMTAG_HEADERSIGNATURES) {
il_max = 32;
dl_max = 64 * 1024;
}

memset(block, 0, sizeof(block));
if ((xx = Freadall(fd, bs, blen)) != blen) {
Expand All @@ -1941,15 +1954,9 @@ rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrbl
goto exit;
}
il = ntohl(block[2]);
if (hdrchkRange(il_max, il)) {
rasprintf(emsg, _("hdr tags: BAD, no. of tags(%d) out of range"), il);
goto exit;
}
dl = ntohl(block[3]);
if (hdrchkRange(dl_max, dl)) {
rasprintf(emsg, _("hdr data: BAD, no. of bytes(%d) out of range"), dl);
if (hdrblobVerifyLengths(regionTag, il, dl, emsg))
goto exit;
}

nb = (il * sizeof(struct entryInfo_s)) + dl;
uc = sizeof(il) + sizeof(dl) + nb;
Expand Down Expand Up @@ -1993,11 +2000,18 @@ rpmRC hdrblobInit(const void *uh, size_t uc,
struct hdrblob_s *blob, char **emsg)
{
rpmRC rc = RPMRC_FAIL;

memset(blob, 0, sizeof(*blob));
if (uc && uc < 8) {
rasprintf(emsg, _("hdr length: BAD"));
goto exit;
}

blob->ei = (int32_t *) uh; /* discards const */
blob->il = ntohl(blob->ei[0]);
blob->dl = ntohl(blob->ei[1]);
blob->il = ntohl((uint32_t)(blob->ei[0]));
blob->dl = ntohl((uint32_t)(blob->ei[1]));
if (hdrblobVerifyLengths(regionTag, blob->il, blob->dl, emsg) != RPMRC_OK)
goto exit;

blob->pe = (entryInfo) &(blob->ei[2]);
blob->pvlen = sizeof(blob->il) + sizeof(blob->dl) +
(blob->il * sizeof(*blob->pe)) + blob->dl;
Expand Down