Bug 741612

Summary: rpm: buffer overflow with malformed archive (copyTdEntry)
Product: [Other] Security Response Reporter: Tavis Ormandy <taviso>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: jrusnack, mjc, pinto.elia, pmatilai, rcvalle
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
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:
Bug Depends On:    
Bug Blocks: 741810    
Description Flags
testcase none

Description Tavis Ormandy 2011-09-27 12:38:43 UTC
Created attachment 525113 [details]

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;

	    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

Comment 2 Tavis Ormandy 2011-09-27 14:34:01 UTC
Marking urgent, because I didn't realise that yum just uses librpm via a native

Also sent a mail to secalert@.

Comment 3 Panu Matilainen 2011-09-28 06:59:23 UTC
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)

Comment 4 devzero2000 2011-09-28 11:05:30 UTC
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]#

Comment 6 Mark J. Cox 2011-09-29 09:20:20 UTC
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 ***