Kort sagt: memory_limit anger hur mycket minne en enskild PHP-förfrågan får uppta; standard är 128M. I normaldrift sätter ni ett ändligt värde som passar applikationen och spärrar det med php_admin_value. Så länge PHP2Shell inte är patchad rekommenderar php.net tillfälligt memory_limit=-1, inte överskrivbart och kombinerat med en gräns via container eller cgroup, inte via RLIMIT_AS eller RLIMIT_DATA. Efter uppdateringen gäller åter ett ändligt värde.
En rutininställning som plötsligt är en säkerhetsfråga
I åratal var memory_limit en justerskruv för utvecklare. Rapporterar en webbplats ”Allowed memory size exhausted” höjs värdet och problemet är avklarat. Med PHP2Shell har det blivit en säkerhetsfråga, och php.nets rekommendation verkar vid första anblicken paradoxal: under övergången ska PHP:s egen minnesgräns helt falla bort.
Bakgrunden är CVE-2026-109618. Enligt PHP-projektet kan ett out-of-memory-tillstånd avbryta PHP medan förfrågningsdata bara är delvis initierade. Städningen av förfrågan kan då behandla ogiltiga data som giltiga. Tekniska detaljer finns under CVE-2026-109618, och vad som händer vid minnesbrist inne i PHP förklarar memory_limit och out-of-memory. För driftansvariga räknas frågan: vilket värde gäller när, och var måste det stå?
Vad memory_limit gör i normaldrift
Enligt PHP-manualen begränsar memory_limit det minne ett skript får uppta och skyddar på så sätt servern mot dåligt skriven kod. Standard är 128M, -1 betyder ingen gräns. Förkortningar som 256M eller 1G är tillåtna.
Två egenskaper är viktiga för säkerheten. För det första går värdet att ändra överallt, även vid körning med ini_set(). Många CMS och butiker höjer det själva, till exempel för importer eller bildbehandling. Den som vill tvinga fram ett värde måste sätta det med php_admin_value; enligt manualen kan värden som sätts så inte skrivas över med ini_set(). För det andra rekommenderar manualen att memory_limit är större än post_max_size.
Vilket värde som passar beror på applikationen. En titt i felloggen visar om meddelanden om slut på minne förekommer och vid vilka anrop. Det har visat sig fungera att fastställa värdet per webbplats i den egna FPM-poolen: generösare för en butik med importer, snävare för en enkel företagssida. Ett generellt mycket högt värde för alla webbplatser slösar bort skyddseffekten, eftersom en enskild felaktig eller missbrukad förfrågan då kan binda mycket minne.
Sedan PHP 8.5 finns dessutom max_memory_limit. Den inställningen kan bara sättas vid start och begränsar hur högt memory_limit överhuvudtaget får sättas. Högre värden kapas med en varning. Standard -1 betyder ingen övre gräns.
memory_limit efter PHP2Shell: php.nets övergångsåtgärd
För servrar som ännu inte är uppdaterade till 8.5.12, 8.4.27, 8.3.36 eller 8.2.35 eller en bekräftad backport nämner php.net i säkerhetsmeddelandet från 21.10.2026 följande steg. De minskar risken för enskilda angreppsvägar men gör enligt php.net ingen installation säker:
- Sätt
memory_limit=-1, helst så att applikationer inte kan skriva över värdet, till exempel medphp_admin_valuei FPM-poolen eller i Apache-konfigurationen. - Kontrollera att ingen ändlig gräns sätts igen någonstans, varken i en annan pool, i en katalogkonfiguration eller i applikationen.
- Sätt en minnesgräns via container eller cgroup, som skydd för tillgängligheten, helst så att bara den berörda workern avslutas vid överskridande.
- Använd inte
RLIMIT_ASellerRLIMIT_DATA. Dessa gränser kan enligt php.net utlösa just det sårbara felet vid minnesbegäran.
php.net förklarar att -1 tar bort möjligheten att målinriktat utlösa PHP:s minnesgräns, men att ett minnesfel på lägre nivå fortfarande kan nå den sårbara vägen. Översikten över alla övergångsåtgärder finns under Akuta åtgärder när ni ännu inte kan patcha.
; FPM-pool, t.ex. /etc/php/8.3/fpm/pool.d/www.conf (bara fram till uppdateringen)
php_admin_value[memory_limit] = -1
# Var memory_limit sätts överallt (bara läsande)
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
Hur ni sätter cgroup-gränsen för FPM-tjänsten beskriver Sätta minnesgränser med systemd och cgroups. Utan den yttre gränsen kan en enskild förfrågan försätta hela servern i minnesnöd.
Starta om alla PHP-workers efter varje ändring. En pågående worker behåller sina gamla värden.
Vad som gäller efter uppdateringen
Med de rättade versionerna har enligt PHP-manualen även beteendet hos memory_limit ändrats. Från och med 8.5.12, 8.4.27, 8.3.36 och 8.2.35 är det en mjuk gräns: en minnesbegäran som överskrider den får i de flesta fall slutföras innan felet utlöses. En ny inställning, memory_hard_limit_percent, fastställer en hård gräns som aldrig överskrids.
| Inställning | Värde | Verkan enligt manualen |
|---|---|---|
memory_hard_limit_percent inte satt eller -1 |
Standard | hård gräns dubbelt så hög som memory_limit upp till 1G, över det memory_limit plus 1G |
memory_hard_limit_percent = 150 |
Exempel | vid memory_limit=128M hård gräns 192M |
memory_limit = -1 |
ingen gräns | då finns heller ingen hård gräns |
Manualen nämner en praktisk kontrollpunkt: känns memory_hard_limit_percent inte igen är den använda PHP-versionen berörd och måste uppdateras. Vid backports från distributioner kontrollerar ni versionen dessutom via paketets changelog.
# Känner FPM-binären till den nya inställningen? (anpassa versionsnumret)
php-fpm8.3 -i | grep -E 'memory_hard_limit_percent|memory_limit'
Efter uppdateringen har memory_limit=-1 fyllt sitt syfte. Återgå till ett ändligt värde som passar applikationen och spärra det med php_admin_value. Cgroup-gränsen kan finnas kvar som ett extra skyddslager.
Hur hjälper PHP SOS konkret?
- Vi tar reda på var
memory_limitsätts och skrivs över på er server, inklusive i applikationerna. - Vi genomför php.nets övergångsåtgärder på rätt ställe och kompletterar med en cgroup-gräns för FPM-tjänsten.
- Via PHP-patchtjänsten tar vi PHP till en rättad version och startar om alla workers.
- Därefter sätter vi åter ett lämpligt ändligt värde och dokumenterar inställningarna.
Vanliga frågor
Vilket är standardvärdet för memory_limit?
Enligt PHP-manualen 128M. Värdet begränsar hur mycket minne ett enskilt skript får uppta. Det kan ändras i php.ini, i serverkonfigurationen, i FPM-poolen och vid körning med ini_set(), om det inte är spärrat med php_admin_value.
Varför rekommenderar php.net memory_limit=-1 vid PHP2Shell?
En av sårbarheterna, CVE-2026-109618, hänger ihop med tillståndet vid minnesbrist. Enligt php.net tar memory_limit=-1 bort möjligheten att målinriktat utlösa PHP:s minnesgräns, men inte varje minnesfel. Åtgärden är inget fullständigt skydd och måste kombineras med en minnesgräns via container eller cgroup.
Får jag i stället sätta gränsen med ulimit?
Nej. php.net avråder uttryckligen från att använda RLIMIT_AS eller RLIMIT_DATA som ersättning, eftersom dessa gränser kan utlösa just det sårbara felet vid minnesbegäran. Rekommenderat är en gräns via container eller cgroup.
Vad gäller efter uppdateringen till en rättad PHP-version?
Enligt manualen är memory_limit i de rättade versionerna en mjuk gräns, kompletterad med en hård gräns via memory_hard_limit_percent. Övergångsåtgärden med -1 har då fyllt sitt syfte, och ett ändligt värde som passar applikationen bör gälla igen.