[media] Fix heap-buffer-overflow in AudioAttributes unmarshalling This CL fixes a heap-buffer-overflow in MediaPlayerService's AudioAttributes unmarshalling logic. The source length was in bytes and the utf16_to_utf8 uses char16_t pointer arithmetic on it that would lead to an OOB read. Corrected the source length parameter to give length as number of char16_t. The destination length has to be 1 less than the actual size of the destination since utf16_to_utf8 adds a NULL terminator. Correct this behaviour to limit the destination length to allocated length - 1. Bug: 482172329 Bug: 396471524 Test: fuzzer with the testcases Test: atest CtsMediaAudioTestCases CtsMediaPlayerTestCases libutils_tests Flag: EXEMPT CVE_FIX Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:50d6c98e00c2c5620ea50e26c9c44e70a0c5ce8a Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:4900a9a6131d54669801e8a547822e63657c3e02 Merged-In: I9f607d57281c76d8e1c1a14112dffdf22acb8080 Change-Id: I9f607d57281c76d8e1c1a14112dffdf22acb8080
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 9e9e9d8..c84c6cd 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -238,15 +238,12 @@ // the tags are UTF16, convert to UTF8 String16 tags = parcel.readString16(); ssize_t realTagSize = utf16_to_utf8_length(tags.string(), tags.size()); - if (realTagSize <= 0) { + if (realTagSize <= 0 || realTagSize >= AUDIO_ATTRIBUTES_TAGS_MAX_SIZE) { strcpy(attributes->tags, ""); } else { // copy the flattened string into the attributes as the destination for the conversion: // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it - size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ? - AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize; - utf16_to_utf8(tags.string(), tagSize, attributes->tags, - sizeof(attributes->tags) / sizeof(attributes->tags[0])); + utf16_to_utf8(tags.string(), tags.size(), attributes->tags, realTagSize); } } else { ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values");