Bug 741612
Summary: | rpm: buffer overflow with malformed archive (copyTdEntry) | ||||||
---|---|---|---|---|---|---|---|
Product: | [Other] Security Response | Reporter: | Tavis Ormandy <taviso> | ||||
Component: | vulnerability | Assignee: | Red Hat Product Security <security-response-team> | ||||
Status: | CLOSED DUPLICATE | QA Contact: | |||||
Severity: | high | Docs Contact: | |||||
Priority: | high | ||||||
Version: | unspecified | CC: | jrusnack, mjc, pinto.elia, pmatilai, rcvalle | ||||
Target Milestone: | --- | Keywords: | Security | ||||
Target Release: | --- | ||||||
Hardware: | Unspecified | ||||||
OS: | Unspecified | ||||||
Whiteboard: | |||||||
Fixed In Version: | Doc Type: | Bug Fix | |||||
Doc Text: | Story Points: | --- | |||||
Clone Of: | Environment: | ||||||
Last Closed: | 2011-09-29 09:20:20 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: | |||||||
Bug Blocks: | 741810 | ||||||
Attachments: |
|
Marking urgent, because I didn't realise that yum just uses librpm via a native wrapper. Also sent a mail to secalert@. Just like bug 741606, this probably affects pretty much every single rpm version ever released. I could only easily test down to rpm-4.4.x (which is certainly affected too), but this is ancient code which hasn't seen much changes in a long long time. Also just like with the other bug, this also is detected by the query code path: [pmatilai@localhost ~]$ rpm -K ~/Downloads/copyTdEntry.rpm Segmentation fault (core dumped) [pmatilai@localhost ~]$ rpm -qp ~/Downloads/copyTdEntry.rpm error: /home/pmatilai/Downloads/copyTdEntry.rpm: headerRead failed: region trailer: BAD, tag 1768846712 type 761753205 offset 0 count 0 error: /home/pmatilai/Downloads/copyTdEntry.rpm: not an rpm package (or package manifest) rpm --checksig copyTdEntry.rpm error: copyTdEntry.rpm: Header: region trailer: BAD, tag 1768846712 type 761753205 offset 0 count 0 [root@kiku rpmb]# rpm --version rpm (RPM) 5.3.9 [root@esil697 rpmb]# [root@kuku rpmb]# cat /etc/redhat-release Mandriva Linux release 2011.0 (Cooker) for x86_64 [root@kuku rpmb]# I'm duping this bug with bz#741606 because this is the same problem as bz#741606#c2, where entry->info.offset is not being validated, it shares the same patch and CVE name as 741606#c2 *** This bug has been marked as a duplicate of bug 741606 *** |
Created attachment 525113 [details] testcase if (ENTRY_IS_REGION(entry)) { int32_t * ei = ((int32_t *)entry->data) - 2; entryInfo pe = (entryInfo) (ei + 2); unsigned char * dataStart = (unsigned char *) (pe + ntohl(ei[0])); int32_t rdl = -entry->info.offset; /* negative offset */ int32_t ril = rdl/sizeof(*pe); rdl = entry->rdlen; count = 2 * sizeof(*ei) + (ril * sizeof(*pe)) + rdl; if (entry->info.tag == HEADER_IMAGE) { ril -= 1; pe += 1; } else { count += REGION_TAG_COUNT; rdl += REGION_TAG_COUNT; } td->data = xmalloc(count); ei = (int32_t *) td->data; ei[0] = htonl(ril); ei[1] = htonl(rdl); pe = (entryInfo) memcpy(ei + 2, pe, (ril * sizeof(*pe))); Has this ever worked? I'm not sure how the rdl/ril calculation can work. With fuzzing I was able to cause a buffer overflow in the signature check. (gdb) r --checksig a (gdb) bt #0 copyTdEntry (entry=0x625110, td=0x7fffffff6010, flags=HEADERGET_DEFAULT) at header.c:1091 #1 0x00007ffff794753e in intGetTdEntry (h=0x622150, td=0x7fffffff6010, flags=HEADERGET_DEFAULT) at header.c:1314 #2 0x00007ffff79475d8 in headerGet (h=0x622150, tag=RPMTAG_HEADERIMMUTABLE, td=0x7fffffff6010, flags=HEADERGET_DEFAULT) at header.c:1337 #3 0x00007ffff797324f in readFile (fd=0x622180, fn=0x60a080 "a", dig=0x622ab0, plbundle=0x6223b0, hdrbundle=0x622420) at rpmchecksig.c:470 #4 0x00007ffff7973c29 in rpmpkgVerifySigs (keyring=0x620ef0, flags=1572865, fd=0x622180, fn=0x60a080 "a") at rpmchecksig.c:689 #5 0x00007ffff797429e in rpmcliSign (ts=0x621630, qva=0x7ffff7bab180, argv=0x609ed8) at rpmchecksig.c:824 #6 0x00000000004036e0 in main (argc=3, argv=0x7fffffffe448) at rpmqv.c:787 (gdb) p ril $14 = -1 (gdb) p ril * sizeof(*pe) $15 = -16 (gdb) c Program received signal SIGSEGV, Segmentation fault. memcpy () at ../sysdeps/x86_64/memcpy.S:434