
WhatsApp के मीडिया पिकर में हीप करप्शन
व्हाट्सएप के मीडिया पिकर में हीप भ्रष्टाचार (heap corruption), जो संस्करण 2.19.291 से पहले के एंड्रॉइड के लिए व्हाट्सएप को प्रभावित करता है।
एक GIF फ़ाइल खंडों में विभाजित होती है, जिन्हें एक विशिष्ट बाइट द्वारा चिह्नित किया जाता है:
स्रोत कोड के अनुसार, renderFrame एक GIF को पार्स करने के लिए DDGifSlurp को कॉल करता है, और GIF प्रदर्शित करने के लिए getBitmap को। एक rasterBits बफ़र फ़ंक्शन द्वारा आवंटित किया जाता है, और इसका आकार वर्तमान में संसाधित की जा रही छवि की चौड़ाई को ऊँचाई से गुणा करके गणना की जाती है। शायद मेमोरी स्थान और समय बचाने के लिए, GIF में सभी फ़्रेमों/छवियों के लिए एक ही rasterBits बफ़र का उपयोग किया जाएगा। इसलिए, यह आवश्यक है कि बफ़र फ़ाइल में वर्णित सबसे बड़ी छवि को समाहित करने में सक्षम हो। इस प्रकार, यदि उसी GIF के भीतर कोई अन्य छवि अनुभाग एक बड़ी छवि का वर्णन करता है (अधिक स्थान की आवश्यकता होती है), तो बफ़र को तदनुसार पुनः आवंटित किया जाता है।
DDGifSlurp GIF फ़ाइल को एक लूप में पार्स करता है, फ़ाइल में प्रत्येक छवि/फ़्रेम को संसाधित करता है, और समाप्ति (terminate) रिकॉर्ड मिलने पर समाप्त हो जाता है। जब DGifGetImageDesc GIF_ERROR लौटाता है (a), तो यह (switch case में) जल्दी समाप्ति का कारण बनता है, जिसके परिणामस्वरूप rasterBits बफ़र को पुनः आवंटित करने वाला कोड छोड़ दिया जाता है। DDGifSlurp का एक स्निपेट नीचे दिखाया गया है:
void DDGifSlurp(GifInfo *info, bool decode, bool exitAfterFrame) {
...
do {
...
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(gifFilePtr, isInitialPass) == GIF_ERROR) { <-- [a]
break;
}
...
if (decode) {
...
const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height;
if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) {
void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, sizeof(GifPixelType));
...
}
}while (RecordType != TERMINATE_RECORD_TYPE);
}
निम्नलिखित प्रारूप वाली एक GIF छवि क्रैश का कारण बनेगी: