diff options
author | Nick Kralevich <nnk@google.com> | 2013-04-29 10:49:47 -0700 |
---|---|---|
committer | Nick Kralevich <nnk@google.com> | 2013-04-29 15:31:03 -0700 |
commit | 6d8f5b755b133b308204b84145d773d401cdcd52 (patch) | |
tree | f5a1c5fe448f583437489277e6e39833dae17d36 | |
parent | 93c39d5d4fe8a31da35f8d1d522acb7b676946af (diff) | |
download | frameworks_base-6d8f5b755b133b308204b84145d773d401cdcd52.zip frameworks_base-6d8f5b755b133b308204b84145d773d401cdcd52.tar.gz frameworks_base-6d8f5b755b133b308204b84145d773d401cdcd52.tar.bz2 |
libdrm: fix bad strncpy / snprintf calls
Fix the following bugs reported by IOActive:
* GOOGLE-AN01 - Android libdrm drm_parseDM.c Boundary-CRLF Buffer Overflow
* GOOGLE-AN02 - Android libdrm 'drm_parseDM.c' contentType-CRLF Buffer Overflow
* GOOGLE-AN03 - Android libdrm drm_parseDM.c contentID-CRLF Buffer Overflow
* GOOGLE-AN04 - Android libdrm 'parser_dcf.c' Multiple Headers Buffer Overflow
* GOOGLE-AN05 - Android libdrm 'parser_dcf.c' ContentType Buffer Overflow
Bug: 8727221
(cherry picked from commit 25619b2c6b3fd584affe20f34bfbf164a5ddbe7d)
Change-Id: I9a99c9b8a63c8b9efb3b2b650c735467b77120f2
-rw-r--r-- | media/libdrm/mobile1/src/parser/parser_dcf.c | 40 | ||||
-rw-r--r-- | media/libdrm/mobile1/src/parser/parser_dm.c | 10 |
2 files changed, 43 insertions, 7 deletions
diff --git a/media/libdrm/mobile1/src/parser/parser_dcf.c b/media/libdrm/mobile1/src/parser/parser_dcf.c index 06aa830..3eac120 100644 --- a/media/libdrm/mobile1/src/parser/parser_dcf.c +++ b/media/libdrm/mobile1/src/parser/parser_dcf.c @@ -58,11 +58,20 @@ int32_t drm_dcfParser(uint8_t *buffer, int32_t bufferLen, T_DRM_DCF_Info *pDcfIn pDcfInfo->Version = *(tmpBuf++); if (0x01 != pDcfInfo->Version) /* Because it is OMA DRM v1.0, the vension must be 1 */ return FALSE; + pDcfInfo->ContentTypeLen = *(tmpBuf++); + if (pDcfInfo->ContentTypeLen >= MAX_CONTENT_TYPE_LEN) + return FALSE; + pDcfInfo->ContentURILen = *(tmpBuf++); + if (pDcfInfo->ContentURILen >= MAX_CONTENT_URI_LEN) + return FALSE; + strncpy((char *)pDcfInfo->ContentType, (char *)tmpBuf, pDcfInfo->ContentTypeLen); + pDcfInfo->ContentType[MAX_CONTENT_TYPE_LEN - 1] = 0; tmpBuf += pDcfInfo->ContentTypeLen; strncpy((char *)pDcfInfo->ContentURI, (char *)tmpBuf, pDcfInfo->ContentURILen); + pDcfInfo->ContentURI[MAX_CONTENT_URI_LEN - 1] = 0; tmpBuf += pDcfInfo->ContentURILen; /* 2. Get the headers length and data length */ @@ -86,30 +95,49 @@ int32_t drm_dcfParser(uint8_t *buffer, int32_t bufferLen, T_DRM_DCF_Info *pDcfIn while ('\r' != *pEnd && pEnd < pData) pEnd++; - if (0 == strncmp((char *)pStart, HEADER_ENCRYPTION_METHOD, HEADER_ENCRYPTION_METHOD_LEN)) + if (0 == strncmp((char *)pStart, HEADER_ENCRYPTION_METHOD, HEADER_ENCRYPTION_METHOD_LEN)) { + if ((pEnd - pStart - HEADER_ENCRYPTION_METHOD_LEN) >= MAX_ENCRYPTION_METHOD_LEN) + return FALSE; strncpy((char *)pDcfInfo->Encryption_Method, (char *)(pStart + HEADER_ENCRYPTION_METHOD_LEN), pEnd - pStart - HEADER_ENCRYPTION_METHOD_LEN); - else if (0 == strncmp((char *)pStart, HEADER_RIGHTS_ISSUER, HEADER_RIGHTS_ISSUER_LEN)) + pDcfInfo->Encryption_Method[MAX_ENCRYPTION_METHOD_LEN - 1] = 0; + } else if (0 == strncmp((char *)pStart, HEADER_RIGHTS_ISSUER, HEADER_RIGHTS_ISSUER_LEN)) { + if ((pEnd - pStart - HEADER_RIGHTS_ISSUER_LEN) >= MAX_RIGHTS_ISSUER_LEN) + return FALSE; strncpy((char *)pDcfInfo->Rights_Issuer, (char *)(pStart + HEADER_RIGHTS_ISSUER_LEN), pEnd - pStart - HEADER_RIGHTS_ISSUER_LEN); - else if (0 == strncmp((char *)pStart, HEADER_CONTENT_NAME, HEADER_CONTENT_NAME_LEN)) + pDcfInfo->Rights_Issuer[MAX_RIGHTS_ISSUER_LEN - 1] = 0; + } else if (0 == strncmp((char *)pStart, HEADER_CONTENT_NAME, HEADER_CONTENT_NAME_LEN)) { + if ((pEnd - pStart - HEADER_CONTENT_NAME_LEN) >= MAX_CONTENT_NAME_LEN) + return FALSE; strncpy((char *)pDcfInfo->Content_Name, (char *)(pStart + HEADER_CONTENT_NAME_LEN), pEnd - pStart - HEADER_CONTENT_NAME_LEN); - else if (0 == strncmp((char *)pStart, HEADER_CONTENT_DESCRIPTION, HEADER_CONTENT_DESCRIPTION_LEN)) + pDcfInfo->Content_Name[MAX_CONTENT_NAME_LEN - 1] = 0; + } else if (0 == strncmp((char *)pStart, HEADER_CONTENT_DESCRIPTION, HEADER_CONTENT_DESCRIPTION_LEN)) { + if ((pEnd - pStart - HEADER_CONTENT_DESCRIPTION_LEN) >= MAX_CONTENT_DESCRIPTION_LEN) + return FALSE; strncpy((char *)pDcfInfo->ContentDescription, (char *)(pStart + HEADER_CONTENT_DESCRIPTION_LEN), pEnd - pStart - HEADER_CONTENT_DESCRIPTION_LEN); - else if (0 == strncmp((char *)pStart, HEADER_CONTENT_VENDOR, HEADER_CONTENT_VENDOR_LEN)) + pDcfInfo->ContentDescription[MAX_CONTENT_DESCRIPTION_LEN - 1] = 0; + } else if (0 == strncmp((char *)pStart, HEADER_CONTENT_VENDOR, HEADER_CONTENT_VENDOR_LEN)) { + if ((pEnd - pStart - HEADER_CONTENT_VENDOR_LEN) >= MAX_CONTENT_VENDOR_LEN) + return FALSE; strncpy((char *)pDcfInfo->ContentVendor, (char *)(pStart + HEADER_CONTENT_VENDOR_LEN), pEnd - pStart - HEADER_CONTENT_VENDOR_LEN); - else if (0 == strncmp((char *)pStart, HEADER_ICON_URI, HEADER_ICON_URI_LEN)) + pDcfInfo->ContentVendor[MAX_CONTENT_VENDOR_LEN - 1] = 0; + } else if (0 == strncmp((char *)pStart, HEADER_ICON_URI, HEADER_ICON_URI_LEN)) { + if ((pEnd - pStart - HEADER_ICON_URI_LEN) >= MAX_ICON_URI_LEN) + return FALSE; strncpy((char *)pDcfInfo->Icon_URI, (char *)(pStart + HEADER_ICON_URI_LEN), pEnd - pStart - HEADER_ICON_URI_LEN); + pDcfInfo->Icon_URI[MAX_ICON_URI_LEN - 1] = 0; + } if ('\n' == *(pEnd + 1)) pStart = pEnd + 2; /* Two bytes: a '\r' and a '\n' */ diff --git a/media/libdrm/mobile1/src/parser/parser_dm.c b/media/libdrm/mobile1/src/parser/parser_dm.c index f5b7aaf..4b4a2da 100644 --- a/media/libdrm/mobile1/src/parser/parser_dm.c +++ b/media/libdrm/mobile1/src/parser/parser_dm.c @@ -90,7 +90,10 @@ int32_t drm_parseDM(const uint8_t *buffer, int32_t bufferLen, T_DRM_DM_Info *pDm /* if can not find the CRLF, return FALSE */ if (NULL == pEnd) return FALSE; + if ((pEnd - pStart) >= MAX_CONTENT_BOUNDARY_LEN) + return FALSE; strncpy((char *)pDmInfo->boundary, (char *)pStart, pEnd - pStart); + pDmInfo->boundary[MAX_CONTENT_BOUNDARY_LEN - 1] = 0; boundaryLen = strlen((char *)pDmInfo->boundary) + 2; /* 2 means: '\r' and '\n' */ pEnd += 2; /* skip the '\r' and '\n' */ @@ -126,6 +129,8 @@ int32_t drm_parseDM(const uint8_t *buffer, int32_t bufferLen, T_DRM_DM_Info *pDm DRM_SKIP_SPACE_TAB(pStart); if (pEnd - pStart > 0) { + if ((pEnd - pStart) >= MAX_CONTENT_TYPE_LEN) + return FALSE; strncpy((char *)pDmInfo->contentType, (char *)pStart, pEnd - pStart); pDmInfo->contentType[pEnd - pStart] = '\0'; } @@ -146,13 +151,16 @@ int32_t drm_parseDM(const uint8_t *buffer, int32_t bufferLen, T_DRM_DM_Info *pDm /* Change the format from <...> to cid:... */ if (NULL != (pTmp = (uint8_t *)memchr((char *)pStart, '<', pEnd - pStart))) { + if ((pEnd - pTmp - 1) >= (int) sizeof(tmpBuf)) + return FALSE; strncpy((char *)tmpBuf, (char *)(pTmp + 1), pEnd - pTmp - 1); + tmpBuf[MAX_CONTENT_ID - 1] = 0; if (NULL != (pTmp = (uint8_t *)memchr((char *)tmpBuf, '>', pEnd - pTmp - 1))) { *pTmp = '\0'; memset(pDmInfo->contentID, 0, MAX_CONTENT_ID); - sprintf((char *)pDmInfo->contentID, "%s%s", "cid:", (int8_t *)tmpBuf); + snprintf((char *)pDmInfo->contentID, MAX_CONTENT_ID, "%s%s", "cid:", (int8_t *)tmpBuf); } } } |