Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 310333 Details for
Bug 452715
CVE-2008-2374 bluez-libs: SDP payload processing vulnerability
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
RHEL-4 bluez-libs patch
bluez-libs-2.10-sdp-vuln.patch (text/plain), 27.25 KB, created by
Bastien Nocera
on 2008-06-26 14:12:29 UTC
(
hide
)
Description:
RHEL-4 bluez-libs patch
Filename:
MIME Type:
Creator:
Bastien Nocera
Created:
2008-06-26 14:12:29 UTC
Size:
27.25 KB
patch
obsolete
>diff -upr bluez-libs-2.10.orig/include/sdp_lib.h bluez-libs-2.10/include/sdp_lib.h >--- bluez-libs-2.10.orig/include/sdp_lib.h 2004-06-17 17:05:33.000000000 +0100 >+++ bluez-libs-2.10/include/sdp_lib.h 2008-06-26 15:07:11.000000000 +0100 >@@ -423,7 +423,8 @@ uuid_t *sdp_uuid_to_uuid128(uuid_t *uuid > void sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16); > int sdp_uuid128_to_uuid(uuid_t *uuid); > int sdp_uuid_to_proto(uuid_t *uuid); >-int sdp_uuid_extract(const char *buffer, uuid_t *uuid, int *scanned); >+int sdp_uuid_extract(const uint8_t *buffer, uuid_t *uuid, int *scanned); >+int sdp_uuid_extract_safe(const uint8_t *buffer, int bufsize, uuid_t *uuid, int *scanned); > void sdp_uuid_print(const uuid_t *uuid); > > #define MAX_LEN_UUID_STR 37 >@@ -537,8 +538,8 @@ static inline uint16_t sdp_gen_tid(sdp_s > return session->tid++; > } > >-sdp_record_t *sdp_extract_pdu(const char *pdata, int *scanned); >-sdp_data_t *sdp_extract_string(char *, int *); >+sdp_record_t *sdp_extract_pdu(const uint8_t *pdata, int *scanned); >+sdp_record_t *sdp_extract_pdu_safe(const uint8_t *pdata, int bufsize, int *scanned); > > void sdp_data_print(sdp_data_t *data); > void sdp_print_service_attr(sdp_list_t *alist); >@@ -553,9 +554,11 @@ void sdp_append_to_buf(sdp_buf_t *dst, c > int sdp_gen_pdu(sdp_buf_t *pdu, sdp_data_t *data); > int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *pdu); > >-int sdp_extract_seqtype(const char *buf, uint8_t *dtdp, int *seqlen); >+int sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *seqlen); >+int sdp_extract_seqtype_safe(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size); > >-sdp_data_t *sdp_extract_attr(const char *pdata, int *extractedLength, sdp_record_t *rec); >+sdp_data_t *sdp_extract_attr(const uint8_t *pdata, int *extractedLength, sdp_record_t *rec); >+sdp_data_t *sdp_extract_attr_safe(const uint8_t *pdata, int bufsize, int *extractedLength, sdp_record_t *rec); > > void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid); > void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq); >diff -upr bluez-libs-2.10.orig/src/sdp.c bluez-libs-2.10/src/sdp.c >--- bluez-libs-2.10.orig/src/sdp.c 2004-07-25 18:09:23.000000000 +0100 >+++ bluez-libs-2.10/src/sdp.c 2008-06-26 15:09:13.000000000 +0100 >@@ -38,6 +38,7 @@ > #include <unistd.h> > #include <stdlib.h> > #include <malloc.h> >+#include <limits.h> > #include <sys/un.h> > #include <sys/socket.h> > >@@ -725,10 +726,69 @@ void sdp_data_free(sdp_data_t *d) > free(d); > } > >-static sdp_data_t *extract_int(const void *p, int *len) >+int sdp_uuid_extract_safe(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned) > { >- sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); >+ uint8_t type; >+ >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ return -1; >+ } >+ >+ type = *(const uint8_t *) p; >+ >+ if (!SDP_IS_UUID(type)) { >+ SDPERR("Unknown data type : %d expecting a svc UUID\n", type); >+ return -1; >+ } >+ p += sizeof(uint8_t); >+ *scanned += sizeof(uint8_t); >+ bufsize -= sizeof(uint8_t); >+ if (type == SDP_UUID16) { >+ if (bufsize < sizeof(uint16_t)) { >+ SDPERR("Not enough room for 16-bit UUID"); >+ return -1; >+ } >+ sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p))); >+ *scanned += sizeof(uint16_t); >+ p += sizeof(uint16_t); >+ } else if (type == SDP_UUID32) { >+ if (bufsize < sizeof(uint32_t)) { >+ SDPERR("Not enough room for 32-bit UUID"); >+ return -1; >+ } >+ sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p))); >+ *scanned += sizeof(uint32_t); >+ p += sizeof(uint32_t); >+ } else { >+ if (bufsize < sizeof(uint128_t)) { >+ SDPERR("Not enough room for 128-bit UUID"); >+ return -1; >+ } >+ sdp_uuid128_create(uuid, p); >+ *scanned += sizeof(uint128_t); >+ p += sizeof(uint128_t); >+ } >+ return 0; >+} > >+int sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned) >+{ >+ /* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN, >+ because we don't have any better information */ >+ return sdp_uuid_extract_safe(p, SDP_MAX_ATTR_LEN, uuid, scanned); >+} >+ >+static sdp_data_t *extract_int(const void *p, int bufsize, int *len) >+{ >+ sdp_data_t *d; >+ >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ return NULL; >+ } >+ >+ d = malloc(sizeof(sdp_data_t)); > SDPDBG("Extracting integer\n"); > memset(d, 0, sizeof(sdp_data_t)); > d->dtd = *(uint8_t *)p; >@@ -741,26 +801,51 @@ static sdp_data_t *extract_int(const voi > case SDP_BOOL: > case SDP_INT8: > case SDP_UINT8: >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ free(d); >+ return NULL; >+ } > *len += sizeof(uint8_t); > d->val.uint8 = *(uint8_t *)p; > break; > case SDP_INT16: > case SDP_UINT16: >+ if (bufsize < sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ free(d); >+ return NULL; >+ } > *len += sizeof(uint16_t); > d->val.uint16 = ntohs(sdp_get_unaligned((uint16_t *)p)); > break; > case SDP_INT32: > case SDP_UINT32: >+ if (bufsize < sizeof(uint32_t)) { >+ SDPERR("Unexpected end of packet"); >+ free(d); >+ return NULL; >+ } > *len += sizeof(uint32_t); > d->val.uint32 = ntohl(sdp_get_unaligned((uint32_t *)p)); > break; > case SDP_INT64: > case SDP_UINT64: >+ if (bufsize < sizeof(uint64_t)) { >+ SDPERR("Unexpected end of packet"); >+ free(d); >+ return NULL; >+ } > *len += sizeof(uint64_t); > d->val.uint64 = ntoh64(sdp_get_unaligned((uint64_t *)p)); > break; > case SDP_INT128: > case SDP_UINT128: >+ if (bufsize < sizeof(uint128_t)) { >+ SDPERR("Unexpected end of packet"); >+ free(d); >+ return NULL; >+ } > *len += sizeof(uint128_t); > ntoh128((uint128_t *)p, &d->val.uint128); > break; >@@ -771,13 +856,13 @@ static sdp_data_t *extract_int(const voi > return d; > } > >-static sdp_data_t *extract_uuid(const void *p, int *len, sdp_record_t *rec) >+static sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len, sdp_record_t *rec) > { > sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); > > SDPDBG("Extracting UUID"); > memset(d, 0, sizeof(sdp_data_t)); >- if (0 > sdp_uuid_extract(p, &d->val.uuid, len)) { >+ if (sdp_uuid_extract_safe(p, bufsize, &d->val.uuid, len) < 0) { > free(d); > return NULL; > } >@@ -789,29 +874,49 @@ static sdp_data_t *extract_uuid(const vo > /* > * Extract strings from the PDU (could be service description and similar info) > */ >-static sdp_data_t *extract_str(const void *p, int *len) >+static sdp_data_t *extract_str(const void *p, int bufsize, int *len) > { > char *s; > int n; >- sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); >+ sdp_data_t *d; >+ >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ return NULL; >+ } >+ >+ d = malloc(sizeof(sdp_data_t)); > > memset(d, 0, sizeof(sdp_data_t)); > d->dtd = *(uint8_t *)p; > p += sizeof(uint8_t); > *len += sizeof(uint8_t); >+ bufsize -= sizeof(uint8_t); > > switch (d->dtd) { > case SDP_TEXT_STR8: > case SDP_URL_STR8: >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ free(d); >+ return NULL; >+ } > n = *(uint8_t *)p; > p += sizeof(uint8_t); >- *len += sizeof(uint8_t) + n; >+ *len += sizeof(uint8_t); >+ bufsize -= sizeof(uint8_t); > break; > case SDP_TEXT_STR16: > case SDP_URL_STR16: >+ if (bufsize < sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ free(d); >+ return NULL; >+ } > n = ntohs(sdp_get_unaligned((uint16_t *)p)); > p += sizeof(uint16_t); > *len += sizeof(uint16_t) + n; >+ bufsize -= sizeof(uint16_t); > break; > default: > SDPERR("Sizeof text string > UINT16_MAX\n"); >@@ -819,10 +924,23 @@ static sdp_data_t *extract_str(const voi > return 0; > } > >+ if (bufsize < n) { >+ SDPERR("String too long to fit in packet"); >+ free(d); >+ return NULL; >+ } >+ > s = malloc(n + 1); >+ if (!s) { >+ SDPERR("Not enough memory for incoming string"); >+ free(d); >+ return NULL; >+ } > memset(s, 0, n + 1); > memcpy(s, p, n); > >+ *len += n; >+ > SDPDBG("Len : %d\n", n); > SDPDBG("Str : %s\n", s); > >@@ -831,7 +949,67 @@ static sdp_data_t *extract_str(const voi > return d; > } > >-static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) >+/* >+ * Extract the sequence type and its length, and return offset into buf >+ * or 0 on failure. >+ */ >+int sdp_extract_seqtype_safe(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size) >+{ >+ uint8_t dtd; >+ int scanned = sizeof(uint8_t); >+ >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ return 0; >+ } >+ >+ dtd = *(uint8_t *) buf; >+ buf += sizeof(uint8_t); >+ bufsize -= sizeof(uint8_t); >+ *dtdp = dtd; >+ switch (dtd) { >+ case SDP_SEQ8: >+ case SDP_ALT8: >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ return 0; >+ } >+ *size = *(uint8_t *) buf; >+ scanned += sizeof(uint8_t); >+ break; >+ case SDP_SEQ16: >+ case SDP_ALT16: >+ if (bufsize < sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ return 0; >+ } >+ *size = ntohs(bt_get_unaligned((uint16_t *) buf)); >+ scanned += sizeof(uint16_t); >+ break; >+ case SDP_SEQ32: >+ case SDP_ALT32: >+ if (bufsize < sizeof(uint32_t)) { >+ SDPERR("Unexpected end of packet"); >+ return 0; >+ } >+ *size = ntohl(bt_get_unaligned((uint32_t *) buf)); >+ scanned += sizeof(uint32_t); >+ break; >+ default: >+ SDPERR("Unknown sequence type, aborting\n"); >+ return 0; >+ } >+ return scanned; >+} >+ >+int sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size) >+{ >+ /* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN, >+ because we don't have any better information */ >+ return sdp_extract_seqtype_safe(buf, SDP_MAX_ATTR_LEN, dtdp, size); >+} >+ >+static sdp_data_t *extract_seq(const void *p, int bufsize, int *len, sdp_record_t *rec) > { > int seqlen, n = 0; > sdp_data_t *curr, *prev; >@@ -839,17 +1017,24 @@ static sdp_data_t *extract_seq(const voi > > SDPDBG("Extracting SEQ"); > memset(d, 0, sizeof(sdp_data_t)); >- *len = sdp_extract_seqtype(p, &d->dtd, &seqlen); >+ *len = sdp_extract_seqtype_safe(p, bufsize, &d->dtd, &seqlen); > SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen); > > if (*len == 0) > return d; > >+ if (*len > bufsize) { >+ SDPERR("Packet not big enough to hold sequence."); >+ free(d); >+ return NULL; >+ } >+ > p += *len; >+ bufsize -= *len; > curr = prev = NULL; > while (n < seqlen) { > int attrlen = 0; >- curr = sdp_extract_attr(p, &attrlen, rec); >+ curr = sdp_extract_attr_safe(p, bufsize, &attrlen, rec); > if (curr == NULL) > break; > >@@ -860,6 +1045,7 @@ static sdp_data_t *extract_seq(const voi > prev = curr; > p += attrlen; > n += attrlen; >+ bufsize -= attrlen; > > SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen); > } >@@ -868,11 +1054,18 @@ static sdp_data_t *extract_seq(const voi > return d; > } > >-sdp_data_t *sdp_extract_attr(const char *p, int *size, sdp_record_t *rec) >+sdp_data_t *sdp_extract_attr_safe(const uint8_t *p, int bufsize, int *size, sdp_record_t *rec) > { > sdp_data_t *elem; > int n = 0; >- uint8_t dtd = *(const uint8_t *)p; >+ uint8_t dtd; >+ >+ if (bufsize < sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet"); >+ return NULL; >+ } >+ >+ dtd = *(const uint8_t *)p; > > SDPDBG("extract_attr: dtd=0x%x", dtd); > switch (dtd) { >@@ -888,12 +1081,12 @@ sdp_data_t *sdp_extract_attr(const char > case SDP_INT32: > case SDP_INT64: > case SDP_INT128: >- elem = extract_int(p, &n); >+ elem = extract_int(p, bufsize, &n); > break; > case SDP_UUID16: > case SDP_UUID32: > case SDP_UUID128: >- elem = extract_uuid(p, &n, rec); >+ elem = extract_uuid(p, bufsize, &n, rec); > break; > case SDP_TEXT_STR8: > case SDP_TEXT_STR16: >@@ -901,7 +1094,7 @@ sdp_data_t *sdp_extract_attr(const char > case SDP_URL_STR8: > case SDP_URL_STR16: > case SDP_URL_STR32: >- elem = extract_str(p, &n); >+ elem = extract_str(p, bufsize, &n); > break; > case SDP_SEQ8: > case SDP_SEQ16: >@@ -909,7 +1102,7 @@ sdp_data_t *sdp_extract_attr(const char > case SDP_ALT8: > case SDP_ALT16: > case SDP_ALT32: >- elem = extract_seq(p, &n, rec); >+ elem = extract_seq(p, bufsize, &n, rec); > break; > default: > SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd); >@@ -919,6 +1112,13 @@ sdp_data_t *sdp_extract_attr(const char > return elem; > } > >+sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) >+{ >+ /* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN, >+ because we don't have any better information */ >+ return sdp_extract_attr_safe(p, SDP_MAX_ATTR_LEN, size, rec); >+} >+ > #ifdef SDP_DEBUG > static void attr_print_func(void *value, void *userData) > { >@@ -940,7 +1140,7 @@ void sdp_print_service_attr(sdp_list_t * > } > #endif > >-sdp_record_t *sdp_extract_pdu(const char *buf, int *scanned) >+sdp_record_t *sdp_extract_pdu_safe(const uint8_t *buf, int bufsize, int *scanned) > { > int extracted = 0, seqlen = 0; > uint8_t dtd; >@@ -948,21 +1148,29 @@ sdp_record_t *sdp_extract_pdu(const char > sdp_record_t *rec = sdp_record_alloc(); > const char *p = buf; > >- *scanned = sdp_extract_seqtype(buf, &dtd, &seqlen); >+ *scanned = sdp_extract_seqtype_safe(buf, bufsize, &dtd, &seqlen); > p += *scanned; >+ bufsize -= *scanned; > rec->attrlist = NULL; >- while (extracted < seqlen) { >+ while (extracted < seqlen && bufsize > 0) { > int n = sizeof(uint8_t), attrlen = 0; > sdp_data_t *data = NULL; > >- SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted); >+ SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", >+ seqlen, extracted); >+ >+ if (bufsize < n + sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ break; >+ } >+ > dtd = *(uint8_t *)p; > attr = ntohs(sdp_get_unaligned((uint16_t *)(p+n))); > n += sizeof(uint16_t); > > SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr); > >- data = sdp_extract_attr(p+n, &attrlen, rec); >+ data = sdp_extract_attr_safe(p + n, bufsize - n, &attrlen, rec); > > SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen); > >@@ -975,9 +1183,11 @@ sdp_record_t *sdp_extract_pdu(const char > rec->handle = data->val.uint32; > extracted += n; > p += n; >+ bufsize -= n; > sdp_attr_replace(rec, attr, data); >+ > SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", >- seqlen, extracted); >+ seqlen, extracted); > } > #ifdef SDP_DEBUG > SDPDBG("Successful extracting of Svc Rec attributes\n"); >@@ -987,6 +1197,13 @@ sdp_record_t *sdp_extract_pdu(const char > return rec; > } > >+sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) >+{ >+ /* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN, >+ because we don't have any better information */ >+ return sdp_extract_pdu_safe(buf, SDP_MAX_ATTR_LEN, scanned); >+} >+ > #ifdef SDP_DEBUG > static void print_dataseq(sdp_data_t *p) > { >@@ -1075,40 +1292,6 @@ sdp_data_t *sdp_data_get(const sdp_recor > return 0; > } > >-/* >- * Extract the sequence type and its length, and return offset into buf >- * or 0 on failure. >- */ >-int sdp_extract_seqtype(const char *buf, uint8_t *dtdp, int *size) >-{ >- uint8_t dtd = *(uint8_t *)buf; >- int scanned = sizeof(uint8_t); >- >- buf += sizeof(uint8_t); >- *dtdp = dtd; >- switch (dtd) { >- case SDP_SEQ8: >- case SDP_ALT8: >- *size = *(uint8_t *)buf; >- scanned += sizeof(uint8_t); >- break; >- case SDP_SEQ16: >- case SDP_ALT16: >- *size = ntohs(sdp_get_unaligned((uint16_t *)buf)); >- scanned += sizeof(uint16_t); >- break; >- case SDP_SEQ32: >- case SDP_ALT32: >- *size = ntohl(sdp_get_unaligned((uint32_t *)buf)); >- scanned += sizeof(uint32_t); >- break; >- default: >- SDPERR("Unknown sequence type, aborting\n"); >- return 0; >- } >- return scanned; >-} >- > int sdp_send_req(sdp_session_t *session, char *buf, int size) > { > int sent = 0; >@@ -2106,32 +2289,6 @@ int sdp_uuid_to_proto(uuid_t *uuid) > return 0; > } > >-int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned) >-{ >- uint8_t type = *(const uint8_t *)p; >- >- if (!SDP_IS_UUID(type)) { >- SDPERR("Unknown data type : %d expecting a svc UUID\n", type); >- return -1; >- } >- p += sizeof(uint8_t); >- *scanned += sizeof(uint8_t); >- if (type == SDP_UUID16) { >- sdp_uuid16_create(uuid, ntohs(sdp_get_unaligned((uint16_t *)p))); >- *scanned += sizeof(uint16_t); >- p += sizeof(uint16_t); >- } else if (type == SDP_UUID32) { >- sdp_uuid32_create(uuid, ntohl(sdp_get_unaligned((uint32_t *)p))); >- *scanned += sizeof(uint32_t); >- p += sizeof(uint32_t); >- } else { >- sdp_uuid128_create(uuid, p); >- *scanned += sizeof(uint128_t); >- p += sizeof(uint128_t); >- } >- return 0; >-} >- > /* > * This function appends data to the PDU buffer "dst" from source "src". > * The data length is also computed and set. >@@ -2258,6 +2415,14 @@ int sdp_record_register(sdp_session_t *s > status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize); > if (status < 0) > goto end; >+ >+ if (rspsize < sizeof(sdp_pdu_hdr_t)) { >+ SDPERR("Unexpected end of packet"); >+ errno = EPROTO; >+ status = -1; >+ goto end; >+ } >+ > rsphdr = (sdp_pdu_hdr_t *)rsp; > p = rsp + sizeof(sdp_pdu_hdr_t); > if (rsphdr->pdu_id == SDP_SVC_REGISTER_RSP) { >@@ -2316,6 +2481,12 @@ int sdp_record_unregister(sdp_session_t > reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); > status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); > if (status == 0) { >+ if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ errno = EPROTO; >+ status = -1; >+ goto end; >+ } > rsphdr = (sdp_pdu_hdr_t *)rspbuf; > p = rspbuf + sizeof(sdp_pdu_hdr_t); > status = sdp_get_unaligned((uint16_t *)p); >@@ -2385,6 +2556,13 @@ int sdp_record_update(sdp_session_t *ses > reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); > status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); > >+ if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ errno = EPROTO; >+ status = -1; >+ goto end; >+ } >+ > SDPDBG("Send req status : %d\n", status); > > if (status == 0) { >@@ -2448,18 +2626,23 @@ void sdp_pattern_add_uuidseq(sdp_record_ > * handles are not in "data element sequence" form, but just like > * an array of service handles > */ >-static void extract_record_handle_seq(char *pdu, sdp_list_t **seq, int count, int *scanned) >+static void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, int *scanned) > { > sdp_list_t *pSeq = *seq; > char *pdata = pdu; > int n; > > for (n = 0; n < count; n++) { >+ if (bufsize < sizeof(uint32_t)) { >+ SDPERR("Unexpected end of packet"); >+ break; >+ } > uint32_t *pSvcRec = (uint32_t *) malloc(sizeof(uint32_t)); > *pSvcRec = ntohl(sdp_get_unaligned((uint32_t *)pdata)); > pSeq = sdp_list_append(pSeq, pSvcRec); > pdata += sizeof(uint32_t); > *scanned += sizeof(uint32_t); >+ bufsize -= sizeof(uint32_t); > } > *seq = pSeq; > } >@@ -2476,7 +2659,7 @@ static int gen_dataseq_pdu(char *dst, co > > // Fill up the value and the dtd arrays > SDPDBG(""); >- >+ > memset(&buf, 0, sizeof(sdp_buf_t)); > buf.data = (char *)malloc(SDP_UUID_SEQ_SIZE); > buf.buf_size = SDP_UUID_SEQ_SIZE; >@@ -2519,12 +2702,17 @@ static int gen_attridseq_pdu(char *dst, > return gen_dataseq_pdu(dst, seq, dataType); > } > >-static int copy_cstate(char *pdata, const sdp_cstate_t *cstate) >+static int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate) > { > if (cstate) { >- *pdata++ = cstate->length; >- memcpy(pdata, cstate->data, cstate->length); >- return cstate->length + 1; >+ uint8_t len = cstate->length; >+ if (len >= pdata_len) { >+ SDPERR("Continuation state size exceeds internal buffer"); >+ len = pdata_len - 1; >+ } >+ *pdata++ = len; >+ memcpy(pdata, cstate->data, len); >+ return len + 1; > } > *pdata = 0; > return 1; >@@ -2571,7 +2759,7 @@ int sdp_service_search_req(sdp_session_t > int reqsize = 0, _reqsize; > int rspsize = 0, rsplen; > int seqlen = 0; >- int scanned, total_rec_count, rec_count; >+ int scanned, total_rec_count, rec_count, pdata_len; > char *pdata, *_pdata; > char *reqbuf, *rspbuf; > sdp_pdu_hdr_t *reqhdr, *rsphdr; >@@ -2609,7 +2797,8 @@ int sdp_service_search_req(sdp_session_t > > do { > // Add continuation state or NULL (first time) >- reqsize = _reqsize + copy_cstate(_pdata, cstate); >+ reqsize = _reqsize + copy_cstate(_pdata, >+ SDP_REQ_BUFFER_SIZE - _reqsize, cstate); > > // Set the request header's param length > reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); >@@ -2623,7 +2812,12 @@ int sdp_service_search_req(sdp_session_t > if (status < 0) > goto end; > >- rsplen = 0; >+ if (rspsize < sizeof(sdp_pdu_hdr_t)) { >+ SDPERR("Unexpected end of packet"); >+ status = -1; >+ goto end; >+ } >+ > rsphdr = (sdp_pdu_hdr_t *)rspbuf; > rsplen = ntohs(rsphdr->plen); > >@@ -2634,14 +2828,23 @@ int sdp_service_search_req(sdp_session_t > } > scanned = 0; > pdata = rspbuf + sizeof(sdp_pdu_hdr_t); >+ pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); >+ >+ if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ status = -1; >+ goto end; >+ } > > // net service record match count > total_rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); > pdata += sizeof(uint16_t); > scanned += sizeof(uint16_t); >+ pdata_len -= sizeof(uint16_t); > rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); > pdata += sizeof(uint16_t); > scanned += sizeof(uint16_t); >+ pdata_len -= sizeof(uint16_t); > > SDPDBG("Total svc count: %d\n", total_rec_count); > SDPDBG("Current svc count: %d\n", rec_count); >@@ -2651,12 +2854,18 @@ int sdp_service_search_req(sdp_session_t > status = -1; > goto end; > } >- extract_record_handle_seq(pdata, rsp, rec_count, &scanned); >+ extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned); > SDPDBG("BytesScanned : %d\n", scanned); > > if (rsplen > scanned) { > uint8_t cstate_len; > >+ if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet: continuation state data missing"); >+ status = -1; >+ goto end; >+ } >+ > pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned; > cstate_len = *(uint8_t *)pdata; > if (cstate_len > 0) { >@@ -2667,7 +2876,7 @@ int sdp_service_search_req(sdp_session_t > } > } while (cstate); > >- end: >+end: > if (reqbuf) > free(reqbuf); > if (rspbuf) >@@ -2715,7 +2924,7 @@ sdp_record_t *sdp_service_attr_req(sdp_s > int reqsize = 0, _reqsize; > int rspsize = 0, rsp_count; > int attr_list_len = 0; >- int seqlen = 0; >+ int seqlen = 0, pdata_len; > char *pdata, *_pdata; > char *reqbuf, *rspbuf; > sdp_pdu_hdr_t *reqhdr, *rsphdr; >@@ -2771,7 +2980,8 @@ sdp_record_t *sdp_service_attr_req(sdp_s > > do { > // add NULL continuation state >- reqsize = _reqsize + copy_cstate(_pdata, cstate); >+ reqsize = _reqsize + copy_cstate(_pdata, >+ SDP_REQ_BUFFER_SIZE - _reqsize, cstate); > > // set the request header's param length > reqhdr->tid = htons(sdp_gen_tid(session)); >@@ -2780,6 +2990,13 @@ sdp_record_t *sdp_service_attr_req(sdp_s > status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); > if (status < 0) > goto end; >+ >+ if (rspsize < sizeof(sdp_pdu_hdr_t)) { >+ SDPERR("Unexpected end of packet"); >+ status = -1; >+ goto end; >+ } >+ > rsp_count = 0; > rsphdr = (sdp_pdu_hdr_t *)rspbuf; > if (rsphdr->pdu_id == SDP_ERROR_RSP) { >@@ -2788,11 +3005,25 @@ sdp_record_t *sdp_service_attr_req(sdp_s > goto end; > } > pdata = rspbuf + sizeof(sdp_pdu_hdr_t); >+ pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); >+ >+ if (pdata_len < sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ status = -1; >+ goto end; >+ } >+ > rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); > attr_list_len += rsp_count; > pdata += sizeof(uint16_t); >+ pdata_len -= sizeof(uint16_t); > > // if continuation state set need to re-issue request before parsing >+ if (pdata_len < rsp_count + sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet: continuation state data missing"); >+ status = -1; >+ goto end; >+ } > cstate_len = *(uint8_t *)(pdata + rsp_count); > > SDPDBG("Response id : %d\n", rsphdr->pdu_id); >@@ -2819,15 +3050,17 @@ sdp_record_t *sdp_service_attr_req(sdp_s > > if (attr_list_len > 0) { > int scanned = 0; >- if (rsp_concat_buf.data_size != 0) >+ if (rsp_concat_buf.data_size != 0) { > pdata = rsp_concat_buf.data; >- rec = sdp_extract_pdu(pdata, &scanned); >+ pdata_len = rsp_concat_buf.data_size; >+ } >+ rec = sdp_extract_pdu_safe(pdata, pdata_len, &scanned); > > if (!rec) > status = -1; > } > >- end: >+end: > if (reqbuf) > free(reqbuf); > if (rsp_concat_buf.data) >@@ -2884,7 +3117,7 @@ int sdp_service_search_attr_req(sdp_sess > int reqsize = 0, _reqsize; > int rspsize = 0; > int seqlen = 0, attr_list_len = 0; >- int rsp_count = 0, cstate_len = 0; >+ int rsp_count = 0, cstate_len = 0, pdata_len; > char *pdata, *_pdata; > char *reqbuf, *rspbuf; > sdp_pdu_hdr_t *reqhdr, *rsphdr; >@@ -2948,12 +3181,19 @@ int sdp_service_search_attr_req(sdp_sess > reqhdr->tid = htons(sdp_gen_tid(session)); > > // add continuation state (can be null) >- reqsize = _reqsize + copy_cstate(_pdata, cstate); >+ reqsize = _reqsize + copy_cstate(_pdata, >+ SDP_REQ_BUFFER_SIZE - _reqsize, cstate); > > // set the request header's param length > reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); > rsphdr = (sdp_pdu_hdr_t *)rspbuf; > status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); >+ if (rspsize < sizeof(sdp_pdu_hdr_t)) { >+ SDPERR("Unexpected end of packet"); >+ status = -1; >+ goto end; >+ } >+ > if (status < 0) { > SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); > goto end; >@@ -2963,11 +3203,33 @@ int sdp_service_search_attr_req(sdp_sess > status = -1; > goto end; > } >- >+ >+ if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ status = -1; >+ goto end; >+ } >+ > pdata = rspbuf + sizeof(sdp_pdu_hdr_t); >+ pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); >+ >+ if (pdata_len < sizeof(uint16_t)) { >+ SDPERR("Unexpected end of packet"); >+ status = -1; >+ goto end; >+ } >+ > rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); > attr_list_len += rsp_count; > pdata += sizeof(uint16_t); // pdata points to attribute list >+ pdata_len -= sizeof(uint16_t); >+ >+ if (pdata_len < rsp_count + sizeof(uint8_t)) { >+ SDPERR("Unexpected end of packet: continuation state data missing"); >+ status = -1; >+ goto end; >+ } >+ > cstate_len = *(uint8_t *)(pdata + rsp_count); > > SDPDBG("Attrlist byte count : %d\n", attr_list_len); >@@ -2994,24 +3256,27 @@ int sdp_service_search_attr_req(sdp_sess > if (attr_list_len > 0) { > int scanned = 0; > >- if (rsp_concat_buf.data_size != 0) >+ if (rsp_concat_buf.data_size != 0) { > pdata = rsp_concat_buf.data; >+ pdata_len = rsp_concat_buf.data_size; >+ } > > /* > * Response is a sequence of sequence(s) for one or > * more data element sequence(s) representing services > * for which attributes are returned > */ >- scanned = sdp_extract_seqtype(pdata, &dataType, &seqlen); >+ scanned = sdp_extract_seqtype_safe(pdata, pdata_len, &dataType, &seqlen); > > SDPDBG("Bytes scanned : %d\n", scanned); > SDPDBG("Seq length : %d\n", seqlen); > > if (scanned && seqlen) { > pdata += scanned; >+ pdata_len -= scanned; > do { > int recsize = 0; >- sdp_record_t *rec = sdp_extract_pdu(pdata, &recsize); >+ sdp_record_t *rec = sdp_extract_pdu_safe(pdata, pdata_len, &recsize); > if (rec == NULL) { > SDPERR("SVC REC is null\n"); > status = -1; >@@ -3019,13 +3284,14 @@ int sdp_service_search_attr_req(sdp_sess > } > scanned += recsize; > pdata += recsize; >+ pdata_len -= recsize; > > SDPDBG("Loc seq length : %d\n", recsize); > SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle); > SDPDBG("Bytes scanned : %d\n", scanned); > SDPDBG("Attrlist byte count : %d\n", attr_list_len); > rec_list = sdp_list_append(rec_list, rec); >- } while (scanned < attr_list_len); >+ } while (scanned < attr_list_len && pdata_len > 0); > > SDPDBG("Successful scan of service attr lists\n"); > *rsp = rec_list;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 452715
:
310163
|
310164
|
310247
|
310250
| 310333 |
310417