Dabartinė padėtis: PHP2Shell. Du kritiniai PHP pažeidžiamumai (CVSS 9,2) leidžia vykdyti kenkėjišką kodą be prisijungimo. Pataisos nuo 2026-10-21.Ką dabar daryti →

memory_limit teisingas nustatymas

memory_limit riboja atmintį vienai PHP užklausai. Po PHP2Shell php.net laikinai pataria priešingai. Kas galioja įprastu režimu, pereinamuoju laikotarpiu ir po atnaujinimo.

Būsena 4 min. skaitymoSutvirtinimas ir konfigūracija

Trumpai: memory_limit nustato, kiek atminties gali užimti viena PHP užklausa; numatytoji reikšmė yra 128M. Įprastu režimu nustatykite baigtinę, programai tinkamą reikšmę ir užrakinkite ją su php_admin_value. Kol PHP2Shell nepataisytas, php.net laikinai pataria memory_limit=-1, neperrašomą ir derinamą su riba per konteinerį ar cgroup, o ne per RLIMIT_AS ar RLIMIT_DATA. Po atnaujinimo vėl galioja baigtinė reikšmė.

Įprastas nustatymas, kuris staiga tapo saugumo tema

Daug metų memory_limit buvo kūrėjų reguliavimo varžtas. Jei svetainė praneša „Allowed memory size exhausted“, reikšmė padidinama ir problema išspręsta. Su PHP2Shell tai tapo saugumo klausimu, o php.net rekomendacija iš pirmo žvilgsnio atrodo paradoksali: pereinamuoju laikotarpiu PHP atminties riba turėtų visiškai išnykti.

Fonas yra CVE-2026-109618. Pasak PHP projekto, atminties trūkumo (Out-of-Memory) būsena gali nutraukti PHP, kol užklausos duomenys inicializuoti tik iš dalies. Tada užklausos sutvarkymas gali netinkamus duomenis traktuoti kaip tinkamus. Techninės detalės pateiktos skyriuje CVE-2026-109618, o kas vyksta PHP viduje trūkstant atminties, paaiškina memory_limit ir Out-of-Memory. Operatoriams svarbus klausimas: kuri reikšmė galioja kada ir kur ji turi būti nustatyta?

Ką memory_limit duoda įprastu režimu

Pasak PHP vadovo, memory_limit riboja atmintį, kurią gali užimti scenarijus, ir taip saugo serverį nuo prastai parašyto kodo. Numatytoji reikšmė yra 128M, -1 reiškia jokios ribos. Leidžiami sutrumpinimai, tokie kaip 256M ar 1G.

Saugumui svarbios dvi savybės. Pirma, reikšmę galima keisti bet kur, taip pat vykdymo metu per ini_set(). Daug CMS ir parduotuvių ją padidina pačios, pavyzdžiui, importams ar vaizdų apdorojimui. Kas nori reikšmę primesti, turi ją nustatyti su php_admin_value; pasak vadovo, taip nustatytų reikšmių negalima perrašyti per ini_set(). Antra, vadovas rekomenduoja, kad memory_limit būtų didesnis už post_max_size.

Kuri reikšmė tinka, priklauso nuo programos. Žvilgsnis į klaidų žurnalą parodo, ar pasitaiko pranešimų apie išsekusią atmintį ir per kokius kreipinius. Pasiteisino reikšmę kiekvienai svetainei nustatyti jos pačios FPM baseine: dosnesnę parduotuvei su importais, kuklesnę paprastam įmonės puslapiui. Bendrai labai didelė reikšmė visoms svetainėms prarandą apsauginį poveikį, nes tada viena klaidinga ar išnaudojama užklausa gali užimti daug atminties.

Nuo PHP 8.5 papildomai yra max_memory_limit. Šį nustatymą galima nustatyti tik paleidžiant, ir jis riboja, kiek aukštai apskritai galima nustatyti memory_limit. Didesnės reikšmės apkarpomos su įspėjimu. Numatytoji -1 reiškia viršutinės ribos nebuvimą.

memory_limit po PHP2Shell: pereinamoji php.net priemonė

Serveriams, kurie dar neatnaujinti iki 8.5.12, 8.4.27, 8.3.36 ar 8.2.35 arba patvirtinto atgalinio pataisų perkėlimo (backport), php.net 2026-10-21 saugumo pranešime nurodo šiuos žingsnius. Jie sumažina atskirų atakos kelių riziką, bet, pasak php.net, įdiegties nepadaro saugios:

  1. Nustatyti memory_limit=-1, pageidautina taip, kad programos negalėtų perrašyti reikšmės, pavyzdžiui, su php_admin_value FPM baseine ar Apache konfigūracijoje.
  2. Patikrinti, kad niekur vėl nenustatoma baigtinė riba, nei kitame baseine, nei katalogo konfigūracijoje, nei programoje.
  3. Nustatyti atminties ribą per konteinerį ar cgroup, kaip prieinamumo apsaugą, pageidautina taip, kad viršijus būtų nutraukiamas tik paveiktas darbinis procesas (worker).
  4. Nenaudoti RLIMIT_AS ar RLIMIT_DATA. Pasak php.net, šios ribos gali sukelti būtent pažeidžiamą klaidą prašant atminties.

php.net šia proga paaiškina, kad -1 pašalina tikslingai sukeliamą PHP atminties ribos pasiekimą, bet žemesnio lygio atminties klaida vis tiek gali pasiekti pažeidžiamą kelią. Visų pereinamųjų priemonių apžvalga pateikta skyriuje Skubios priemonės, kai dar negalite pataisyti.

; FPM baseinas, pvz., /etc/php/8.3/fpm/pool.d/www.conf (tik iki atnaujinimo)
php_admin_value[memory_limit] = -1
# Kur visur nustatomas memory_limit (tik skaitymas)
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

Kaip nustatyti cgroup ribą FPM paslaugai, aprašo Atminties ribų nustatymas su systemd ir cgroups. Be šios išorinės ribos viena užklausa gali sukelti atminties stygių visam serveriui.

Svarbu

Po kiekvieno pakeitimo iš naujo paleiskite visus PHP darbinius procesus (worker). Veikiantis darbinis procesas išlaiko savo senas reikšmes.

Kas galioja po atnaujinimo

Su ištaisytomis versijomis, pasak PHP vadovo, pasikeitė ir memory_limit elgsena. Nuo 8.5.12, 8.4.27, 8.3.36 ir 8.2.35 tai yra minkšta riba: atminties prašymui, kuris ją viršija, daugeliu atvejų leidžiama dar užbaigti prieš sukeliant klaidą. Naujas nustatymas, memory_hard_limit_percent, nustato kietą ribą, kuri niekada neviršijama.

Nustatymas Reikšmė Poveikis pasak vadovo
memory_hard_limit_percent nenustatytas arba -1 numatytasis kieta riba dvigubai didesnė už memory_limit iki 1G, virš to memory_limit plius 1G
memory_hard_limit_percent = 150 pavyzdys esant memory_limit=128M kieta riba 192M
memory_limit = -1 jokios ribos tada nėra ir kietos ribos

Vadovas nurodo praktinį patikros tašką: jei memory_hard_limit_percent neatpažįstamas, naudojama PHP versija yra paveikta ir turi būti atnaujinta. Esant distribucijų atgaliniams pataisų perkėlimams (backport), būseną papildomai patikrinkite per paketo pakeitimų žurnalą.

# Ar FPM vykdomasis failas pažįsta naują nustatymą? (pritaikyti versijos numerį)
php-fpm8.3 -i | grep -E 'memory_hard_limit_percent|memory_limit'

Po atnaujinimo memory_limit=-1 atliko savo paskirtį. Grįžkite prie baigtinės, programai tinkamos reikšmės ir užrakinkite ją su php_admin_value. cgroup riba gali likti kaip papildomas apsaugos sluoksnis.

Kaip PHP SOS padeda konkrečiai?

  • Išsiaiškiname, kur jūsų serveryje nustatomas ir perrašomas memory_limit, įskaitant programas.
  • php.net pereinamąsias priemones įgyvendiname tinkamoje vietoje ir papildome cgroup riba FPM paslaugai.
  • Per PHP pataisų paslaugą PHP atnaujiname iki ištaisytos būsenos ir iš naujo paleidžiame visus darbinius procesus (worker).
  • Po to vėl nustatome tinkamą baigtinę reikšmę ir dokumentuojame nustatymus.

Dažni klausimai

Kokia yra numatytoji memory_limit reikšmė?

Pasak PHP vadovo, 128M. Reikšmė riboja, kiek atminties gali užimti vienas scenarijus. Ją galima keisti php.ini, serverio konfigūracijoje, FPM baseine ir vykdymo metu per ini_set(), jei ji neužrakinta su php_admin_value.

Kodėl php.net dėl PHP2Shell pataria memory_limit=-1?

Vienas iš pažeidžiamumų, CVE-2026-109618, susijęs su būsena trūkstant atminties. Pasak php.net, memory_limit=-1 pašalina tikslingai sukeliamą PHP atminties ribos pasiekimą, bet ne kiekvieną atminties klaidą. Priemonė nėra pilna apsauga ir turi būti derinama su atminties riba per konteinerį ar cgroup.

Ar vietoj to galiu nustatyti ribą su ulimit?

Ne. php.net aiškiai pataria nenaudoti RLIMIT_AS ar RLIMIT_DATA kaip pakaitalo, nes šios ribos gali sukelti būtent pažeidžiamą klaidą prašant atminties. Rekomenduojama riba per konteinerį ar cgroup.

Kas galioja po atnaujinimo į ištaisytą PHP versiją?

Pasak vadovo, ištaisytose versijose memory_limit yra minkšta riba, papildyta kieta riba per memory_hard_limit_percent. Pereinamoji priemonė su -1 tada atliko savo paskirtį ir vėl turėtų galioti baigtinė, programai tinkama reikšmė.

Šaltiniai

Skubus kontaktas

Kiekviena valanda svarbi. Parašykite mums dabar.

Trumpai aprašykite sistemą, PHP versiją ir pastebėjimus. Mes atsakysime, išsiaiškinsime padėtį ir dirbsime nuotoliu, kol incidentas bus užbaigtas ir dokumentuotas.

Skubi pagalba