summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sdp_lib.h4
-rw-r--r--src/sdp.c30
2 files changed, 27 insertions, 7 deletions
diff --git a/include/sdp_lib.h b/include/sdp_lib.h
index 2323abfc..8df540c6 100644
--- a/include/sdp_lib.h
+++ b/include/sdp_lib.h
@@ -585,9 +585,11 @@ static inline int sdp_get_icon_url(const sdp_record_t *rec, char *str, int len)
return sdp_get_string_attr(rec, SDP_ATTR_ICON_URL, str, len);
}
-sdp_record_t *sdp_extract_pdu(const uint8_t *pdata, int *scanned);
sdp_data_t *sdp_extract_string(uint8_t *, 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);
diff --git a/src/sdp.c b/src/sdp.c
index 977f6660..b9b0e4f6 100644
--- a/src/sdp.c
+++ b/src/sdp.c
@@ -1323,7 +1323,7 @@ void sdp_print_service_attr(sdp_list_t *svcAttrList)
}
#endif
-sdp_record_t *sdp_extract_pdu(const uint8_t *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;
@@ -1331,21 +1331,30 @@ sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned)
sdp_record_t *rec = sdp_record_alloc();
const uint8_t *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(bt_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);
@@ -1363,9 +1372,11 @@ sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned)
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");
@@ -1375,6 +1386,13 @@ sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned)
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)
{