Bug 497990 (CVE-2009-1574)

Summary: CVE-2009-1574 ipsec-tools: racoon NULL dereference in fragmentation code
Product: [Other] Security Response Reporter: Tomas Hoger <thoger>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: kreilly, mjc, tmraz, vdanen
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: 2010-03-29 09:18:32 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: 498881, 498882, 833913    
Bug Blocks:    

Description Tomas Hoger 2009-04-28 09:58:57 UTC
ipsec-tools upstream version 0.7.2 announcement mentions following security fix:

  o Fix a remote crash in fragmentation code

http://sourceforge.net/project/shownotes.php?group_id=74601&release_id=677611

Upstream CVS commit provides further details:

  From Neil Kettle: Fix a possible null pointer dereference in
  fragmentation code.

http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src/racoon/isakmp_frag.c?f=h#rev1.4.6.1
http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src/racoon/isakmp_frag.c.diff?r1=1.4&r2=1.4.6.1&f=h

Comment 1 Tomas Hoger 2009-04-28 10:09:10 UTC
Further details:

Upstream patch adds check "ntohs(frag->len) < sizeof(*frag) + 1" to isakmp_frag_extract(), line 203 (code is from fixed 0.7.2):

202     if (msg->l < sizeof(*isakmp) + ntohs(frag->len) ||
203         ntohs(frag->len) < sizeof(*frag) + 1) {
204         plog(LLV_ERROR, LOCATION, NULL, "Fragment too short\n");
205         return -1;
206     }

Without this check, vmalloc argument computation may integer-underflow:

208     if ((buf = vmalloc(ntohs(frag->len) - sizeof(*frag))) == NULL) {
209         plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
210         return -1;
211     }

This should only be a problem when ntohs(frag->len) == sizeof(*frag), as vmalloc does:

 58     if ((var = (vchar_t *)racoon_malloc(sizeof(*var))) == NULL)
 59         return NULL;
 60         
 61     var->l = size;
 62     if (size == 0) {
 63         var->v = NULL;
 64     } else { 
 65         var->v = (caddr_t)racoon_calloc(1, size);
 66         if (var->v == NULL) {
 67             (void)racoon_free(var);
 68             return NULL;
 69         }
 70     }   

When ntohs(frag->len) == sizeof(*frag), vmalloc returns var with var->v NULL and var->l 0.  For ntohs(frag->len) < sizeof(*frag), size would wrap to a high positive value (close to 2^32 or 2^64, based on architecture), resulting in racoon_calloc on line 65 to return NULL (or, unlikely, return requested large memory chunk) and vmalloc returning NULL too.

If vmalloc returns not-NULL, but bug->v is NULL, NULL pointer dereference happens:

219     data = (char *)(frag + 1);
220     memcpy(buf->v, data, buf->l);

Comment 2 Tomas Hoger 2009-04-28 10:33:50 UTC
This issue affects ipsec-tools in Red Hat Enterprise Linux 5 (based on upstream 0.6.5), versions in Red Hat Enterprise Linux 4 (0.3.3) and 3 (0.2.5) are not affected, as they do not include support for handling fragmented isakmp packets.

Comment 4 Tomas Hoger 2009-04-29 11:34:27 UTC
(In reply to comment #1)
> If vmalloc returns not-NULL, but bug->v is NULL, NULL pointer dereference
> happens:
> 
> 219     data = (char *)(frag + 1);
> 220     memcpy(buf->v, data, buf->l);  

Actually, no NULL deref here yet, as buf->l is 0 too.  NULL deref happens bit later.  When all fragments are read, isakmp_frag_extract() returns 1.  This causes frag_handler() to call isakmp_frag_reassembly():

3024     if (isakmp_frag_extract(iph1, msg) == 1) {
3025         if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) {
3026             plog(LLV_ERROR, LOCATION, remote,
3027                 "Packet reassembly failed\n");
3028             return -1;
3029         }
3030         return isakmp_main(newmsg, remote, local);

Which computes size of reassembled packet as sum of lengths of all fragments:

282     do {
283         frag_count++;
284         len += item->frag_packet->l;
285         item = item->frag_next;
286     } while (item != NULL);

Buffer for reassembled packet is allocated using vmalloc:

288     if ((buf = vmalloc(len)) == NULL) {

and all fragments are copied to it.  If all fragments have length 0, isakmp_frag_reassembly() returns { NULL, 0 }, which is passed to isakmp_main() as newmsg / msg.  In isakmp_main, this happens:

 394 isakmp_main(msg, remote, local)
 395     vchar_t *msg;
 396     struct sockaddr *remote, *local;
 397 {
 398     struct isakmp *isakmp = (struct isakmp *)msg->v;
  // the above is NULL
  [ ... ]
 400     u_int32_t msgid = isakmp->msgid;

Comment 8 Fedora Update System 2009-05-05 14:43:22 UTC
ipsec-tools-0.7.2-1.fc9 has been submitted as an update for Fedora 9.
http://admin.fedoraproject.org/updates/ipsec-tools-0.7.2-1.fc9

Comment 9 Fedora Update System 2009-05-05 14:44:06 UTC
ipsec-tools-0.7.2-1.fc10 has been submitted as an update for Fedora 10.
http://admin.fedoraproject.org/updates/ipsec-tools-0.7.2-1.fc10

Comment 10 Fedora Update System 2009-05-05 14:46:06 UTC
ipsec-tools-0.7.2-1.fc11 has been submitted as an update for Fedora 11.
http://admin.fedoraproject.org/updates/ipsec-tools-0.7.2-1.fc11

Comment 11 Vincent Danen 2009-05-06 22:03:00 UTC
Common Vulnerabilities and Exposures assigned an identifier CVE-2009-1574 to
the following vulnerability:

Name: CVE-2009-1574
URL: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-1574
Assigned: 20090506

racoon/isakmp_frag.c in ipsec-tools before 0.7.2 allows remote
attackers to cause a denial of service (crash) via crafted fragmented
packets without a payload, which triggers a NULL pointer dereference.

Comment 12 errata-xmlrpc 2009-05-18 20:09:55 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

Via RHSA-2009:1036 https://rhn.redhat.com/errata/RHSA-2009-1036.html

Comment 13 Fedora Update System 2009-05-19 02:00:23 UTC
ipsec-tools-0.7.2-1.fc9 has been pushed to the Fedora 9 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 14 Fedora Update System 2009-05-19 02:04:22 UTC
ipsec-tools-0.7.2-1.fc10 has been pushed to the Fedora 10 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 15 Fedora Update System 2009-05-19 02:11:30 UTC
ipsec-tools-0.7.2-1.fc11 has been pushed to the Fedora 11 stable repository.  If problems still persist, please make note of it in this bug report.