Trenutno stanje: PHP2Shell. Dve kritični ranljivosti PHP (CVSS 9,2) omogočata izvedbo škodljive kode brez prijave. Popravki od 21. 10. 2026.Kaj je zdaj treba storiti →

memory_limit in Out-of-Memory: kaj se dogaja v notranjosti

Kaj se zgodi, ko skripta PHP naleti na memory_limit? Mehanika, nova trda meja pomnilnika od oktobrskih popravkov in povezava s CVE-2026-109618.

Stanje 5 min branjaZnanje o PHP

Na kratko: Napaka PHP Out-of-Memory nastane, ko skripta želi zahtevati več pomnilnika, kot dovoljuje nastavitev memory_limit (privzeto: 128 MB na zahtevo). PHP nato zahtevo prekine s smrtno napako in pospravi. Prav ta pot prekinitve in čiščenja je bila pri CVE-2026-109618, eni od obeh ranljivosti PHP2Shell, napačna. Od PHP 8.5.12, 8.4.27, 8.3.36 in 8.2.35 je memory_limit mehka meja, dopolnjena s trdo mejo memory_hard_limit_percent.

Kaj pomeni „Allowed memory size exhausted“?

Znano sporočilo o napaki se po pomenu glasi: „Allowed memory size of 134217728 bytes exhausted (tried to allocate …)“. Prva številka je nastavljena omejitev v bajtih, tu 128 MB. Skripta je torej poskusila zasesti pomnilnik čez to mejo, na primer pri nalaganju velike datoteke, ogromni poizvedbi v podatkovni bazi ali zaradi neskončne zanke.

Za odločevalce pomembno: meja velja za vsak proces PHP in vsako zahtevo, ne za celoten strežnik. Strežnik ščiti pred tem, da bi posamezna napačna skripta porabila ves pomnilnik. Skupna obremenitev izhaja šele iz števila hkrati tekočih workerjev. Pri 20 workerjih PHP-FPM z mejo po 256 MB je to računsko več kot 5 GB.

Kako PHP šteje pomnilnik

PHP pomnilnik za zahteve upravlja prek lastnega upravljalnika pomnilnika, Zend Memory Manager. Večje bloke vzame pri operacijskem sistemu in jih interno razdeli spremenljivkam, poljem in objektom. Glede na to rezervirano vrednost PHP preverja memory_limit. Pomnilnik, ki ga razširitev zahteva neposredno pri operacijskem sistemu, se po priročniku v tem štetju ne pojavi.

Vrednosti lahko naredite vidne v kodi:

<?php
echo memory_get_usage(), PHP_EOL;       // trenutno pomnilnik, ki ga zaseda skripta
echo memory_get_usage(true), PHP_EOL;   // rezervira upravljalnik pomnilnika; glede na to preverja memory_limit
$liste = range(1, 200000);
echo memory_get_peak_usage(), PHP_EOL;  // dosedanja najvišja vrednost
unset($liste);
memory_reset_peak_usage();              // ponastavitev najvišje vrednosti, od PHP 8.2

Kako štetje sklicev in garbage collection pomnilnik znova sprostita, razlaga stran Upravljanje pomnilnika v PHP.

Kaj se ob Out-of-Memory dogaja v notranjosti

Poenostavljeno prekinitev zaradi pomnilnika poteka v teh korakih:

  1. Skripta zahteva pomnilnik, na primer za nov element polja ali pri branju podatkov zahteve.
  2. Upravljalnik pomnilnika preveri, ali zahteva presega mejo.
  3. Če je tako, PHP sproži smrtno napako in takoj zapusti tekočo obdelavo, tudi sredi napol opravljene naloge.
  4. Registrirane funkcije za zaustavitev (shutdown) se še izvedejo; številne aplikacije z njimi zabeležijo napako.
  5. Na koncu PHP zahtevo pospravi in sprosti njen pomnilnik. Worker je nato pripravljen za naslednjo zahtevo.

Občutljiva točka je korak 5. Čiščenje se mora znati spoprijeti s podatkovnimi strukturami, ki so bile ob prekinitvi šele napol ustvarjene. Običajna prekinitev zaradi pomnilnika po varnostni politiki projekta PHP ni varnostna vrzel, dokler meja zahtevo zavrne in se konča le trenutna zahteva. Pri CVE-2026-109618 je bila prav ta predpostavka kršena: po navedbah php.net je stanje Out-of-Memory lahko prekinilo PHP, medtem ko so bili notranji podatki zahteve le delno inicializirani, čiščenje pa je nato neveljavne podatke obravnavalo kot veljavne. Podrobnosti izkoriščanja ne objavljamo; uvrstitev ranljivosti je pod CVE-2026-109618.

Nova mehka in trda meja pomnilnika

Z varnostnimi izdajami z dne 21. 10. 2026 je projekt PHP spremenil obnašanje. Po priročniku je memory_limit od takrat mehka meja: zahtevo, ki jo preseže, je v večini primerov še dovoljeno dokončati, preden sledi smrtna napaka. Ločena trda meja omejuje, kako daleč lahko to gre.

Direktiva Privzeto Spremenljivo Pomen
memory_limit 128M INI_ALL meja pomnilnika na zahtevo, -1 = brez meje
memory_hard_limit_percent ni nastavljeno INI_ALL trda meja v odstotkih memory_limit, novo od 8.5.12, 8.4.27, 8.3.36, 8.2.35
post_max_size 8M INI_PERDIR največja velikost podatkov POST
upload_max_filesize 2M INI_PERDIR največja velikost naložene datoteke

Primer iz priročnika: pri memory_limit=128M in memory_hard_limit_percent=150 je trda meja pri 192 MB. Priročnik direktivo hkrati navaja kot znak za prepoznavo: če je različica PHP ne pozna, sta jo prizadeli CVE-2026-109618 in CVE-2026-109619. Hiter test za vsako nameščeno različico PHP:

php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
# bool(false) pomeni: direktiva neznana

Pri paketih iz distribucij z backportom ostaja merodajno dokazilo dnevnik sprememb paketa, kot je opisano v Pravilno preverjanje različice PHP in stanja popravkov. Poleg tega ločeno preverite binarno datoteko PHP-FPM, saj ima lahko drugo različico kot ukazna vrstica.

Meje pomnilnika in PHP2Shell: na kaj morajo skrbniki paziti zdaj

Prehodni ukrepi php.net za CVE-2026-109618 se skoraj vsi vrtijo okoli pomnilnika in velikosti zahtev. Tveganje zmanjšujejo, posodobitve pa ne nadomestijo:

; pool FPM, npr. /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M        ; 32M, če je nalaganje potrebno
php_admin_value[upload_max_filesize] = 6M  ; ostati pod post_max_size

Pomembne so tri točke. Prvič, nobena aplikacija, noben imenik in noben drug pool ne sme znova nastaviti končne meje; php.net to kontrolo izrecno zahteva. Drugič, storitev z memory_limit=-1 potrebuje zunanjo mejo, prek vsebnika ali cgroup, po php.net najbolje tako, da se konča samo prizadeti worker. RLIMIT_AS in RLIMIT_DATA sta po php.net neprimerna. Tretjič, php.net priporoča meje na spletnem strežniku ali proxyju za velikost zahteve, število polj, dele multipart, glave in globino gnezdenja.

Pomembno

memory_limit=-1 brez zunanje meje pomnilnika lahko strežnik pri veliki obremenitvi popolnoma ohromi. Prehodne ukrepe uvedite samo kot paket in samo do posodobitve.

Kako mejo nastaviti s systemd, je opisano v Meje pomnilnika s systemd in cgroups; trajno rešitev za vsakdan opisuje Pravilna nastavitev memory_limit.

Kako PHP SOS pomaga konkretno?

Prek storitve popravljanja PHP ravnamo takole:

  • Preveriti stanje: zajamemo vsako različico PHP na strežniku, ločeno po CLI, FPM in modulu Apache, ter preizkusimo, ali teče popravljena različica.
  • Urediti meje pomnilnika: preverimo, kje vse je nastavljen memory_limit, in meje poolov ter sistema nastavimo tako, da se ujemajo.
  • Zavarovati prehod: kjer je posodobitev še blokirana, ukrepe php.net uvedemo v celoti in zaklenjene proti prepisovanju.
  • Predložiti dokazilo: različice, stanja paketov in konfiguracijo pred posegom in po njem prejmete pisno.

Pogosta vprašanja

Kaj pomeni sporočilo „Allowed memory size exhausted“?

Skripta je želela zahtevati več pomnilnika, kot dovoljuje memory_limit. PHP nato tekočo zahtevo prekine s smrtno napako. Druge zahteve in sam strežnik tečejo naprej.

Ali memory_limit velja za celoten strežnik?

Ne, meja velja za vsak proces PHP in zahtevo. Če teče 20 workerjev FPM z mejo po 256 MB, lahko skupaj teoretično zasedejo več kot 5 GB. Skupno mejo je zato treba določiti prek velikosti poola, systemd ali vsebnika.

Kaj je memory_hard_limit_percent?

Nova direktiva, ki je prišla s PHP 8.5.12, 8.4.27, 8.3.36 in 8.2.35. Določa trdo mejo kot odstotek memory_limit, ki je nikoli ni mogoče preseči. memory_limit sam je od takrat mehka meja.

Ali memory_limit=-1 ščiti pred PHP2Shell?

Le delno. php.net nastavitev navaja kot prehodni ukrep proti CVE-2026-109618, izrecno brez popolne zaščite. Nujno potrebuje zunanjo mejo pomnilnika, posodobitev pa ostaja obvezna.

Viri

Takojšnji stik

Vsaka ura šteje. Pišite nam zdaj.

Na kratko opišite sistem, različico PHP in opažanje. Odzovemo se, razjasnimo stanje in delamo na daljavo, dokler incident ni zaključen in dokumentiran.

Takojšnja pomoč