Aktuālā situācija: PHP2Shell. Divas kritiskas PHP ievainojamības (CVSS 9.2) ļauj izpildīt ļaunprātīgu kodu bez pieteikšanās. Ielāpi kopš 21.10.2026.Kas jādara tagad →

memory_limit un Out-of-Memory: kas notiek iekšienē

Kas notiek, kad PHP skripts sasniedz memory_limit? Mehānika, jaunā stingrā atmiņas robeža kopš oktobra ielāpiem un saistība ar CVE-2026-109618.

Aktuāls uz 5 min lasīšanas laiksPHP zināšanas

Īsi: PHP Out-of-Memory kļūda rodas, kad skripts mēģina pieprasīt vairāk atmiņas, nekā atļauj iestatījums memory_limit (noklusējums: 128 MB katram pieprasījumam). PHP tad pārtrauc pieprasījumu ar fatālu kļūdu un uzkopj. Tieši šis pārtraukšanas un uzkopšanas ceļš bija kļūdains CVE-2026-109618, vienā no abām PHP2Shell ievainojamībām. Kopš PHP 8.5.12, 8.4.27, 8.3.36 un 8.2.35 memory_limit ir mīksta robeža, ko papildina stingrā robeža memory_hard_limit_percent.

Ko nozīmē „Allowed memory size exhausted“?

Pazīstamais kļūdas ziņojums pēc nozīmes skan: „Allowed memory size of 134217728 bytes exhausted (tried to allocate …)“. Pirmais skaitlis ir iestatītais limits baitos, šeit 128 MB. Skripts tātad mēģināja aizņemt atmiņu pāri šai robežai, piemēram, ielādējot lielu failu, milzīgu datubāzes vaicājumu vai bezgalīgas cilpas dēļ.

Lēmumu pieņēmējiem svarīgi: robeža attiecas uz katru PHP procesu un katru pieprasījumu, nevis uz visu serveri. Tā sargā serveri no tā, ka viens kļūdains skripts patērē visu atmiņu. Kopējā slodze rodas tikai no vienlaikus darbojošos darbprocesu skaita. Ar 20 PHP-FPM darbprocesiem ar 256 MB robežu katrs tas rēķinot ir vairāk nekā 5 GB.

Kā PHP skaita atmiņu

PHP pieprasījumu atmiņu pārvalda ar savu atmiņas pārvaldnieku, Zend Memory Manager. Tas ņem lielākus blokus no operētājsistēmas un iekšēji sadala tos mainīgajiem, masīviem un objektiem. Pret šo rezervēto vērtību PHP pārbauda memory_limit. Atmiņa, ko paplašinājums pieprasa tieši pie operētājsistēmas, saskaņā ar rokasgrāmatu šajā uzskaitē neparādās.

Vērtības kodā var padarīt redzamas:

<?php
echo memory_get_usage(), PHP_EOL;       // pašlaik skripta aizņemtā atmiņa
echo memory_get_usage(true), PHP_EOL;   // atmiņas pārvaldnieka rezervētā; pret to pārbauda memory_limit
$liste = range(1, 200000);
echo memory_get_peak_usage(), PHP_EOL;  // līdzšinējais maksimums
unset($liste);
memory_reset_peak_usage();              // atiestatīt maksimumu, no PHP 8.2

Kā atsauču skaitīšana un Garbage Collection atmiņu atbrīvo atpakaļ, izskaidro lapa Atmiņas pārvaldība PHP.

Kas Out-of-Memory brīdī notiek iekšienē

Vienkāršoti atmiņas pārtraukšana norit šādos soļos:

  1. Skripts pieprasa atmiņu, piemēram, jaunam masīva elementam vai pieprasījuma datu nolasīšanai.
  2. Atmiņas pārvaldnieks pārbauda, vai pieprasījums pārsniedz robežu.
  3. Ja tā ir, PHP izraisa fatālu kļūdu un nekavējoties pamet notiekošo apstrādi, arī uzdevuma vidū, kas izpildīts tikai uz pusi.
  4. Reģistrētās shutdown funkcijas vēl darbojas; ar tām daudzas lietojumprogrammas reģistrē kļūdu žurnālā.
  5. Beigās PHP uzkopj pieprasījumu un atbrīvo tā atmiņu. Darbprocess pēc tam ir gatavs nākamajam pieprasījumam.

Delikātais punkts ir 5. solis. Uzkopšanai jāspēj tikt galā ar datu struktūrām, kas pārtraukšanas brīdī bija izveidotas tikai uz pusi. Parasta atmiņas pārtraukšana saskaņā ar PHP projekta drošības politiku nav ievainojamība, kamēr limits pieprasījumu noraida un beidzas tikai pašreizējais pieprasījums. CVE-2026-109618 gadījumā tieši šis pieņēmums bija pārkāpts: saskaņā ar php.net Out-of-Memory stāvoklis varēja pārtraukt PHP, kamēr iekšējie pieprasījuma dati bija inicializēti tikai daļēji, un uzkopšana nederīgus datus tad apstrādāja kā derīgus. Detaļas par izmantošanu mēs nepublicējam; ievainojamības klasifikācija atrodama sadaļā CVE-2026-109618.

Jaunā mīkstā un stingrā atmiņas robeža

Ar drošības izlaidumiem no 21.10.2026 PHP projekts uzvedību mainīja. Saskaņā ar rokasgrāmatu memory_limit kopš tā laika ir mīksta robeža: pieprasījumu, kas to pārsniedz, vairumā gadījumu vēl drīkst pabeigt, pirms seko fatālā kļūda. Atsevišķa stingrā robeža ierobežo, cik tālu tas drīkst iet.

Direktīva Noklusējums Maināma Nozīme
memory_limit 128M INI_ALL atmiņas robeža katram pieprasījumam, -1 = nav robežas
memory_hard_limit_percent nav iestatīts INI_ALL stingrā robeža procentos no memory_limit, jauna kopš 8.5.12, 8.4.27, 8.3.36, 8.2.35
post_max_size 8M INI_PERDIR POST datu maksimālais izmērs
upload_max_filesize 2M INI_PERDIR vienas augšupielādēta faila maksimālais izmērs

Piemērs no rokasgrāmatas: ar memory_limit=128M un memory_hard_limit_percent=150 stingrā robeža ir 192 MB. Rokasgrāmata direktīvu vienlaikus min kā atpazīšanas pazīmi: ja PHP versija to nepazīst, uz to attiecas CVE-2026-109618 un CVE-2026-109619. Ātrs tests katrai instalētajai PHP versijai:

php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
# bool(false) nozīmē: direktīva nav zināma

Distributīvu pakotnēm ar backport noteicošais pierādījums paliek pakotnes changelog, kā aprakstīts sadaļā PHP versijas un ielāpu stāvokļa pareiza pārbaude. Papildus atsevišķi pārbaudiet PHP-FPM binārfailu, jo tam var būt cita versija nekā komandrindai.

Atmiņas robežas un PHP2Shell: kas administratoriem tagad jāņem vērā

php.net pagaidu pasākumi attiecībā uz CVE-2026-109618 gandrīz visi saistīti ar atmiņu un pieprasījumu izmēriem. Tie mazina risku, bet neaizstāj atjauninājumu:

; FPM pūls, piemēram, /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M        ; 32M, ja vajadzīgas augšupielādes
php_admin_value[upload_max_filesize] = 6M  ; turēt zem post_max_size

Svarīgi trīs punkti. Pirmkārt, neviena lietojumprogramma, neviens direktorijs un neviens cits pūls nedrīkst atkal iestatīt ierobežotu robežu; php.net šo kontroli skaidri prasa. Otrkārt, pakalpojumam ar memory_limit=-1 nepieciešama robeža no ārpuses, ar konteineru vai cgroup, pēc php.net vislabāk tā, lai tiktu pārtraukts tikai skartais darbprocess. RLIMIT_AS un RLIMIT_DATA saskaņā ar php.net nav piemēroti. Treškārt, php.net iesaka robežas tīmekļa serverī vai starpniekserverī pieprasījuma izmēram, lauku skaitam, multipart daļām, galvenēm un ligzdošanas dziļumam.

Svarīgi

memory_limit=-1 bez atmiņas robežas no ārpuses lielā slodzē var pilnībā paralizēt serveri. Pagaidu pasākumus iestatiet tikai kā komplektu un tikai līdz atjauninājumam.

Kā robežu iestatīt ar systemd, rakstīts sadaļā Atmiņas robežas ar systemd un cgroups; ilgtermiņa risinājumu ikdienai apraksta memory_limit pareiza iestatīšana.

Kā PHP SOS palīdz konkrēti?

Ar PHP ielāpu servisa palīdzību rīkojamies šādi:

  • Pārbaudīt esošo stāvokli: mēs uzskaitām katru PHP versiju serverī, nodalot CLI, FPM un Apache moduli, un pārbaudām, vai darbojas labotā versija.
  • Sakārtot atmiņas robežas: mēs pārbaudām, kur visur tiek iestatīts memory_limit, un iestatām pūla un sistēmas robežas tā, lai tās saskanētu.
  • Nodrošināt pāreju: kur atjauninājums vēl ir bloķēts, mēs pilnībā ieviešam php.net pasākumus un aizsargājam tos pret pārrakstīšanu.
  • Sniegt pierādījumu: jūs rakstiski saņemat versijas, pakotņu stāvokli un konfigurāciju pirms un pēc iejaukšanās.

Biežāk uzdotie jautājumi

Ko nozīmē ziņojums „Allowed memory size exhausted“?

Skripts mēģināja pieprasīt vairāk atmiņas, nekā atļauj memory_limit. PHP tad pārtrauc notiekošo pieprasījumu ar fatālu kļūdu. Citi pieprasījumi un pats serveris turpina darboties.

Vai memory_limit attiecas uz visu serveri?

Nē, robeža attiecas uz katru PHP procesu un pieprasījumu. Ja darbojas 20 FPM darbprocesi ar 256 MB robežu katrs, kopā tie teorētiski var aizņemt vairāk nekā 5 GB. Kopējā robeža tāpēc jāiestata ar pūla izmēru, systemd vai konteineru.

Kas ir memory_hard_limit_percent?

Jauna direktīva, kas parādījās ar PHP 8.5.12, 8.4.27, 8.3.36 un 8.2.35. Tā nosaka stingru robežu kā memory_limit procentuālu vērtību, ko nekad nepārsniedz. memory_limit pats kopš tā laika ir mīksta robeža.

Vai memory_limit=-1 pasargā no PHP2Shell?

Tikai daļēji. php.net iestatījumu min kā pagaidu pasākumu pret CVE-2026-109618, skaidri norādot, ka tā nav pilnīga aizsardzība. Tai noteikti nepieciešama atmiņas robeža no ārpuses, un atjauninājums paliek obligāts.

Avoti

Tūlītējs kontakts

Katra stunda ir svarīga. Rakstiet mums tūlīt.

Īsi aprakstiet sistēmu, PHP versiju un novēroto. Mēs sazināsimies, noskaidrosim situāciju un strādāsim attālināti, līdz incidents ir slēgts un dokumentēts.

Tūlītēja palīdzība