Bug 1273360 - rpm: crash when parsing corrupted RPM file
Summary: rpm: crash when parsing corrupted RPM file
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
low
low
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1278797
Blocks: 1270711
TreeView+ depends on / blocked
 
Reported: 2015-10-20 09:38 UTC by Stefan Cornelius
Modified: 2019-09-29 13:38 UTC (History)
5 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2016-10-28 08:27:51 UTC
Embargoed:


Attachments (Terms of Use)

Description Stefan Cornelius 2015-10-20 09:38:29 UTC
t was discovered that rpm did not properly parse certain corrupt RPM files. This can be exploited to cause a crash by tricking an unsuspecting user into processing a specially crafted RPM file.

Comment 2 Stefan Cornelius 2015-10-20 14:46:20 UTC
I think the problem is within the "CompressFilelist()" function in lib/legacy.c.

It allocates memory to store filename data from the header:
50 baseNames = xmalloc(sizeof(*dirNames) * count);

It then attempts to do some processing in order to fill this memory with sane data:
 72     while ((i = rpmtdNext(&fileNames)) >= 0) {
 73     char ** needle;
 74     char savechar;
 75     char * baseName;
 76     size_t len;
 77     char *filename = (char *) rpmtdGetString(&fileNames); /* HACK HACK */
 78
 79     if (filename == NULL)    /* XXX can't happen */
 80         continue;
 81     baseName = strrchr(filename, '/') + 1;
 82     len = baseName - filename;
 83     needle = dirNames;
 84     savechar = *baseName;
 85     *baseName = '\0';
 86     if (dirIndex < 0 ||
 87         (needle = bsearch(&filename, dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
 88         char *s = xmalloc(len + 1);
 89         rstrlcpy(s, filename, len + 1);
 90         dirIndexes[i] = ++dirIndex;
 91         dirNames[dirIndex] = s;
 92     } else
 93         dirIndexes[i] = needle - dirNames;
 94
 95     *baseName = savechar;
 96     baseNames[i] = baseName;
 97     }
 98
 99 exit:
100     if (count > 0) {
101     headerPutUint32(h, RPMTAG_DIRINDEXES, dirIndexes, count);
102     headerPutStringArray(h, RPMTAG_BASENAMES, baseNames, count);
103     headerPutStringArray(h, RPMTAG_DIRNAMES,
104                  (const char **) dirNames, dirIndex + 1);

In case of the rpm provided, the (filename == NULL) check in line 79 will be true in every iteration, thus the remaining processing steps in this loop are always skipped and "baseNames" is never put in a state that's expected by subsequent functions, which are called via headerPutStringArray() in line 102. This will ultimately lead to a crash due to invalid memory access in a strlen() function.

Comment 7 Stefan Cornelius 2015-11-06 12:53:09 UTC
Created rpm tracking bugs for this issue:

Affects: fedora-all [bug 1278797]

Comment 8 Fedora Update System 2015-11-23 20:53:27 UTC
rpm-4.13.0-0.rc1.7.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report.

Comment 9 Fedora Update System 2015-11-30 23:22:23 UTC
rpm-4.12.0.1-14.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.