
Corruption de tas dans le sélecteur de médias de WhatsApp
Corruption de tas dans le sélecteur de médias de WhatsApp affectant WhatsApp pour Android avant la version 2.19.291
Un fichier GIF est divisé en segments, marqués par un octet spécifique :
D'après le code source, renderFrame appelle DDGifSlurp pour analyser un GIF, et getBitmap pour afficher le GIF. Un tampon rasterBits est alloué par la fonction, et sa taille est calculée en multipliant la largeur par la hauteur de l'image en cours de traitement. Peut-être pour économiser de la mémoire et du temps, le même tampon rasterBits sera utilisé pour toutes les images du GIF. Par conséquent, il est nécessaire que le tampon puisse contenir la plus grande image décrite dans le fichier. Ainsi, le tampon est réalloué en conséquence si une autre section image du même GIF décrit une image plus grande (nécessitant plus d'espace).
DDGifSlurp analyse le fichier GIF dans une boucle, traitant chaque image du fichier, et se termine lorsque l'enregistrement de terminaison est rencontré. Lorsque DGifGetImageDesc retourne GIF_ERROR (a), cela entraîne une terminaison anticipée (dans le cas du switch), ce qui fait que le code de réallocation du tampon rasterBits est sauté. Un extrait de DDGifSlurp est présenté ci-dessous :
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);
}
Une image GIF ayant le format suivant provoquera un crash :