Bug 1273360
| Summary: | rpm: crash when parsing corrupted RPM file | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | Stefan Cornelius <scorneli> |
| Component: | vulnerability | Assignee: | Red Hat Product Security <security-response-team> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | low | Docs Contact: | |
| Priority: | low | ||
| Version: | unspecified | CC: | ffesti, jorton, jrusnack, scorneli, security-response-team |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2016-10-28 08:27:51 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | 1278797 | ||
| Bug Blocks: | 1270711 | ||
|
Description
Stefan Cornelius
2015-10-20 09:38:29 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.
Created rpm tracking bugs for this issue: Affects: fedora-all [bug 1278797] 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. 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. |