Em resumo: O memory_limit define quanta memória um único pedido PHP pode ocupar; o valor por defeito é 128M. Em operação normal, defina um valor finito adequado à aplicação e bloqueie-o com php_admin_value. Enquanto o PHP2Shell não estiver corrigido, o php.net aconselha temporariamente memory_limit=-1, que não possa ser sobrescrito e combinado com um limite através de contentor ou cgroup, não através de RLIMIT_AS ou RLIMIT_DATA. Depois da atualização, volta a valer um valor finito.
Uma definição de rotina que de repente é um tema de segurança
Durante anos, o memory_limit foi um parâmetro para programadores. Se um site comunica «Allowed memory size exhausted», aumenta-se o valor e o problema fica resolvido. Com o PHP2Shell, passou a ser uma questão de segurança, e a recomendação do php.net parece, à primeira vista, paradoxal: para a fase transitória, o limite de memória do próprio PHP deve ser totalmente eliminado.
O contexto é a CVE-2026-109618. Segundo o projeto PHP, um estado de falta de memória pode interromper o PHP enquanto os dados do pedido estão apenas parcialmente inicializados. A limpeza do pedido pode então tratar dados inválidos como válidos. Os pormenores técnicos estão em CVE-2026-109618; o que acontece no interior do PHP em caso de falta de memória é explicado em memory_limit e Out-of-Memory. Para os operadores, a questão é: que valor vale quando, e onde tem de estar?
O que o memory_limit faz em operação normal
Segundo o manual do PHP, o memory_limit limita a memória que um script pode ocupar e protege assim o servidor de código mal escrito. O valor por defeito é 128M, e -1 significa sem limite. São permitidas notações abreviadas como 256M ou 1G.
Duas características são importantes para a segurança. Primeiro, o valor pode ser alterado em qualquer lado, também em tempo de execução com ini_set(). Muitos CMS e lojas aumentam-no por si próprios, por exemplo para importações ou processamento de imagens. Quem quiser impor um valor tem de o definir com php_admin_value; segundo o manual, os valores assim definidos não podem ser sobrescritos com ini_set(). Segundo, o manual recomenda que o memory_limit seja superior a post_max_size.
O valor adequado depende da aplicação. Uma vista ao registo de erros mostra se ocorrem mensagens de memória esgotada e em que chamadas. Tem-se revelado eficaz definir o valor para cada site no respetivo pool FPM: mais generoso para uma loja com importações, mais curto para um site institucional simples. Um valor muito alto e generalizado para todos os sites desperdiça o efeito protetor, porque então um único pedido defeituoso ou abusivo pode ocupar muita memória.
Desde o PHP 8.5 existe ainda max_memory_limit. Esta definição só pode ser fixada no arranque e limita até que valor o memory_limit pode ser definido. Os valores mais altos são cortados com um aviso. O valor por defeito -1 significa que não há limite máximo.
memory_limit após o PHP2Shell: a medida transitória do php.net
Para servidores que ainda não foram atualizados para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, ou para um backport confirmado, o php.net indica, no comunicado de segurança de 21/10/2026, os seguintes passos. Reduzem o risco de alguns caminhos de ataque, mas, segundo o php.net, não tornam uma instalação segura:
- Definir
memory_limit=-1, se possível de modo que as aplicações não possam sobrescrever o valor, por exemplo comphp_admin_valueno pool FPM ou na configuração do Apache. - Verificar que em lado nenhum volta a ser definido um limite finito, nem noutro pool, nem numa configuração de diretório, nem na aplicação.
- Definir um limite de memória através de contentor ou cgroup, como proteção da disponibilidade, se possível de modo que, em caso de excesso, apenas o worker afetado seja terminado.
- Não usar
RLIMIT_ASnemRLIMIT_DATA. Segundo o php.net, esses limites podem desencadear precisamente o erro vulnerável na atribuição de memória.
O php.net explica a este respeito que -1 elimina a possibilidade de atingir de forma provocada o limite de memória do PHP, mas que um erro de memória a um nível mais profundo pode continuar a alcançar o caminho vulnerável. A visão geral de todas as medidas transitórias está em Medidas imediatas, quando ainda não pode aplicar o patch.
; Pool FPM, p. ex. /etc/php/8.3/fpm/pool.d/www.conf (apenas até à atualização)
php_admin_value[memory_limit] = -1
# Onde é definido o memory_limit (apenas leitura)
grep -rn 'memory_limit' /etc/php/ /etc/apache2/ 2>/dev/null
grep -rn --include='*.php' -E "ini_set\s*\(\s*['\"]memory_limit" /var/www | head -20
grep -rn --include='.user.ini' 'memory_limit' /var/www
Como definir o limite cgroup para o serviço FPM é descrito em Definir limites de memória com systemd e cgroups. Sem este limite exterior, um único pedido pode levar o servidor inteiro a uma situação de falta de memória.
Após cada alteração, reinicie todos os workers PHP. Um worker em execução mantém os valores antigos.
O que vale depois da atualização
Com as versões corrigidas, segundo o manual do PHP, também mudou o comportamento do memory_limit. A partir de 8.5.12, 8.4.27, 8.3.36 e 8.2.35, é um limite flexível: um pedido de memória que o ultrapasse pode, na maioria dos casos, ainda ser concluído antes de o erro ser desencadeado. Uma nova definição, memory_hard_limit_percent, estabelece um limite rígido que nunca é excedido.
| Definição | Valor | Efeito segundo o manual |
|---|---|---|
memory_hard_limit_percent não definido ou -1 |
por defeito | limite rígido duas vezes superior ao memory_limit até 1G; acima disso, memory_limit mais 1G |
memory_hard_limit_percent = 150 |
exemplo | com memory_limit=128M, limite rígido de 192M |
memory_limit = -1 |
sem limite | então também não há limite rígido |
O manual indica um ponto de verificação prático: se memory_hard_limit_percent não for reconhecido, a versão do PHP em uso está afetada e tem de ser atualizada. Nos backports das distribuições, verifique o estado também através do changelog do pacote.
# O binário FPM conhece a nova definição? (ajustar o número de versão)
php-fpm8.3 -i | grep -E 'memory_hard_limit_percent|memory_limit'
Após a atualização, o memory_limit=-1 cumpriu a sua finalidade. Volte a um valor finito, adequado à aplicação, e bloqueie-o com php_admin_value. O limite cgroup pode manter-se como camada de proteção adicional.
Como ajuda concretamente a PHP SOS?
- Determinamos onde, no seu servidor, o
memory_limité definido e sobrescrito, incluindo pelas aplicações. - Aplicamos as medidas transitórias do php.net no sítio certo e acrescentamos um limite cgroup para o serviço FPM.
- Através do serviço de patches PHP, levamos o PHP para uma versão corrigida e reiniciamos todos os workers.
- Depois, voltamos a definir um valor finito adequado e documentamos as definições.
Perguntas frequentes
Qual é o valor por defeito do memory_limit?
Segundo o manual do PHP, 128M. O valor limita a memória que um único script pode ocupar. Pode ser alterado no php.ini, na configuração do servidor, no pool FPM e em tempo de execução com ini_set(), desde que não esteja bloqueado com php_admin_value.
Por que razão o php.net recomenda memory_limit=-1 no caso do PHP2Shell?
Uma das vulnerabilidades, a CVE-2026-109618, está relacionada com o estado em caso de falta de memória. Segundo o php.net, memory_limit=-1 elimina a possibilidade de atingir de forma provocada o limite de memória do PHP, mas não todos os erros de memória. A medida não é uma proteção completa e tem de ser combinada com um limite de memória através de contentor ou cgroup.
Posso, em alternativa, definir o limite com ulimit?
Não. O php.net desaconselha expressamente usar RLIMIT_AS ou RLIMIT_DATA como substituto, porque esses limites podem desencadear precisamente o erro vulnerável na atribuição de memória. Recomenda-se um limite através de contentor ou cgroup.
O que vale depois da atualização para uma versão corrigida do PHP?
Segundo o manual, nas versões corrigidas o memory_limit é um limite flexível, complementado por um limite rígido através de memory_hard_limit_percent. A medida transitória com -1 cumpriu então a sua finalidade e deve voltar a aplicar-se um valor finito, adequado à aplicação.