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: | vulnerability | Assignee: | Red Hat Product Security <security-response-team> |
| Status: | CLOSED ERRATA | QA Contact: | |
| Severity: | high | Docs Contact: | |
| Priority: | high | ||
| Version: | unspecified | CC: | 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
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);
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. (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; 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 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 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 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. 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 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. 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. 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. |