{"id":20508,"date":"2026-06-16T17:37:30","date_gmt":"2026-06-16T14:37:30","guid":{"rendered":"https:\/\/sysadmin.courses\/copy-fail-cve-2026-31431-732-%d0%b1%d0%b0%d0%b9%d1%82%d0%b0-python-%d0%b8-%d0%bb%d1%8e%d0%b1%d0%be%d0%b9-%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d1%82%d0%b5%d0%bb%d1%8c-%d1%81\/"},"modified":"2026-06-16T18:50:29","modified_gmt":"2026-06-16T15:50:29","slug":"copy-fail-cve-2026-31431-732-python-baitai-ir-bet-kuris-vartotojas-tampa-root","status":"publish","type":"post","link":"https:\/\/sysadmin.courses\/lt\/copy-fail-cve-2026-31431-732-python-baitai-ir-bet-kuris-vartotojas-tampa-root\/","title":{"rendered":"Copy Fail (CVE-2026-31431): 732 Python baitai \u2014 ir bet kuris vartotojas tampa root"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Theori tyr\u0117jas Taeyang Lee analizavo, kas nutinka, kai Linux kriptografin\u0117 posistem\u0117 per sistemin\u012f i\u0161kvietim\u0105 splice() gauna duomenis tiesiai i\u0161 puslapio pod\u0117lio. Intuicija rod\u0117: jei neprivilegijuotas vartotojas gali pateikti branduolio atmintyje saugom\u0105 failo puslap\u012f \u0161ifravimo operacijai, ka\u017ekas turi nueiti negerai. Jis paleido dirbtinio intelekto \u012frank\u012f Xint Code tikrinti vis\u0105 kriptografinio posistemo kod\u0105, pasiekiam\u0105 i\u0161 vartotojo erdv\u0117s, \u2014 ir ma\u017edaug po valandos ekrane pasirod\u0117 CVE-2026-31431.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Copy Fail yra login\u0117 klaida Linux branduolio kriptografiniame \u0161ablone <code>authencesn<\/code> (CWE-787, ra\u0161ymas u\u017e buferio rib\u0173). Ji leid\u017eia neprivilegijuotam vietiniam vartotojui \u012fra\u0161yti lygiai 4 baitus \u012f bet kurio jam skaitomo failo puslapio pod\u0117l\u012f. Jei taikiniu pasirinksite setuid dvejetain\u012f fail\u0105 \u2014 pavyzd\u017eiui, <code>\/usr\/bin\/su<\/code> \u2014 tai tiesus kelias \u012f root. CVSS 7.8, High. Koncepcijos \u012frodymo eksploitas paskelbtas 2026 m. baland\u017eio 29 d. ir telpa \u012f 732 Python baitus. Pataisymas jau pagrindin\u0117je branduolio versijoje; distribucijos i\u0161leido atnaujinimus \u012fprastu branduolio paketo mechanizmu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tai, kas i\u0161skiria Copy Fail i\u0161 kit\u0173 \u0161i\u0173 met\u0173 LPE pa\u017eeid\u017eiamybi\u0173, yra determinizmas. Dirty Cow reikalavo laim\u0117ti lenktyni\u0173 s\u0105lyg\u0105 ir neretai sugriaudavo sistem\u0105 nes\u0117km\u0117s atveju. Dirty Pipe veik\u0117 tik konkre\u010diose branduolio versijose. Copy Fail suveikia be lenktyni\u0173, be pakartojim\u0173, be riziking\u0173 laiko lang\u0173. Tas pats 732 bait\u0173 scenarijus be pakeitim\u0173 suteikia root Ubuntu, Amazon Linux, RHEL ir SUSE \u2014 jokie atskiri poslinkiai kiekvienai distribucijai, jokie perkompiliavimai. 100% patikimumas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>KAS YRA AF_ALG IR PUSLAPIO POD\u0116LIS<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AF_ALG \u2014 tai lizdo tipas, atveriantis branduolio kriptografin\u0119 posistem\u0119 neprivilegijuotai vartotojo erdvei. Sukuriate lizd\u0105, prisiregistruojate prie bet kurio AEAD \u0161ablono (Authenticated Encryption with Associated Data) ir perduodate duomenis \u0161ifravimui ar de\u0161ifravimui. Joki\u0173 teisi\u0173 nereikia \u2014 tai standartin\u0117 funkcija, prieinama bet kuriam vartotojui.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Puslapio pod\u0117lis \u2014 tai branduolio atminties sluoksnis, kuriame saugomas fail\u0173 turinys. Kai skaitote fail\u0105, branduolys \u012fkelia jo puslapius \u012f pod\u0117l\u012f. Visos v\u0117lesn\u0117s operacijos <code>read()<\/code>, <code>mmap()<\/code> ir <code>execve()<\/code> dirba su \u0161iuo pod\u0117liu, o ne tiesiogiai su disku. Puslapio pod\u0117lis bendras visai sistemai \u2014 \u012fskaitant visus konteinerius, veikian\u010dius serveryje.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sisteminis i\u0161kvietimas <code>splice()<\/code> perduoda duomenis tarp fail\u0173 deskriptori\u0173 ir vamzd\u017ei\u0173 be kopijavimo \u2014 perduodama ne turinys, o nuoroda \u012f atminties puslap\u012f. Kai vartotojas daro <code>splice()<\/code> failo \u012f AF_ALG lizd\u0105, kriptografin\u0117 posistem\u0117 gauna tiesiogines nuorodas \u012f to failo puslapio pod\u0117lio puslapius. Ne kopijas \u2014 lygiai tuos pa\u010dius fizinius puslapius, i\u0161 kuri\u0173 branduolys skaitys fail\u0105 kito <code>execve()<\/code> metu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>KAIP VEIKIA KLAIDA<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AEAD de\u0161ifravimo per AF_ALG metu \u012fvesties srautas atrodo taip: AAD (susietos autentifikavimo duomenys) || \u0161ifratekstas || autentifikavimo \u017eyma. Kodas faile <code>algif_aead.c<\/code> nustato operacij\u0105 vietoje (in-place): tas pats i\u0161sklaidytasis s\u0105ra\u0161as (scatterlist) tarnauja ir kaip \u012fvestis, ir kaip i\u0161vestis. AAD ir \u0161ifratekstas kopijuojami i\u0161 TX buferio \u012f RX bufer\u012f per <code>memcpy_sglist<\/code>. Ta\u010diau \u017eyma \u2014 paskutiniai keli \u012fvesties baitai \u2014 nekopijuojama. Vietoj to puslapio pod\u0117lio puslapiai su \u017eyma prijungiami prie i\u0161vesties i\u0161sklaidytojo s\u0105ra\u0161o per <code>sg_chain()<\/code>. Galiausiai i\u0161vesties i\u0161sklaidytasis s\u0105ra\u0161as atrodo taip: vartotojo RX buferis || tikslinio failo puslapio pod\u0117lio puslapiai.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u010cia \u012f \u017eaidim\u0105 \u012f\u017eengia <code>authencesn<\/code>. Tai AEAD apvalkalas IPsec protokolui su i\u0161pl\u0117stini\u0173 sekos numeri\u0173 palaikymu. IPsec 64 bit\u0173 sekos numeris suskaidytas \u012f vyresn\u012fj\u012f pus\u0119 (seqno_hi, AAD baitai 0\u20133) ir jaunesn\u012fj\u012f (seqno_lo, baitai 4\u20137). HMAC skai\u010diavimui <code>authencesn<\/code> turi perstatyti \u0161iuos baitus \u2014 ir tam naudoja paskirties i\u0161sklaidyt\u0105j\u012f s\u0105ra\u0161\u0105 kaip laikin\u0105 darbo erdv\u0119. Konkre\u010diai: funkcija <code>crypto_authenc_esn_decrypt()<\/code> vykdo i\u0161kvietim\u0105 <code>scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1)<\/code> \u2014 4 bait\u0173 \u012fra\u0161ym\u0105 \u012f pozicij\u0105 <code>assoclen + cryptlen<\/code>, tai yra i\u0161 karto u\u017e autentifikavimo \u017eymos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u012eprastomis s\u0105lygomis tai b\u016bt\u0173 vartotojo buferio sritis. Ta\u010diau kai \u017eymos puslapiai prijungti per <code>sg_chain()<\/code> prie i\u0161vesties i\u0161sklaidytojo s\u0105ra\u0161o \u2014 <code>scatterwalk<\/code> pereina i\u0161 RX buferio tiesiai \u012f tikslinio failo puslapio pod\u0117l\u012f ir \u012fra\u0161o 4 baitus, kuriuos visi\u0161kai kontroliuoja u\u017epuolikas. HMAC tikrinimas stringa, <code>recvmsg()<\/code> gr\u0105\u017eina klaid\u0105 \u2014 ta\u010diau 4 baitai jau \u012fra\u0161yti. Branduolys nepa\u017eymi puslapio kaip pakeisto, tod\u0117l failas diske lieka nepakeistas. Pakeitimas tik atmintyje \u2014 bet b\u016btent i\u0161 atminties branduolys skaito fail\u0105 <code>execve()<\/code> metu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>KAIP TAI I\u0160NAUDOJAMA<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">U\u017epuolikas visi\u0161kai kontroliuoja tris \u012fra\u0161ymo parametrus: kur\u012f fail\u0105 (bet kur\u012f, skaitom\u0105 dabartiniam vartotojui), koki\u0105 pozicij\u0105 failo viduje (per splice poslinkio, ilgio ir assoclen pasirinkim\u0105), ir koki\u0105 reik\u0161m\u0119 \u012fra\u0161yti (sendmsg AAD baitai 4\u20137). Tai ne atsitiktinis perra\u0161ymas \u2014 tai tikslus, kartojamas, programuojamas savavali\u0161kos reik\u0161m\u0117s \u012fra\u0161ymas \u012f savavali\u0161k\u0105 bet kurio failo puslapio pod\u0117lio pozicij\u0105.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eksploitas nukreiptas \u012f <code>\/usr\/bin\/su<\/code> \u2014 setuid-root dvejetain\u012f fail\u0105, esant\u012f visose testuotose distribucijose. Pirmiausia atidaromas AF_ALG lizdas ir prisiregistruojama prie \u0161ablono <code>authencesn(hmac(sha256),cbc(aes))<\/code>. Nustatomas raktas. Priimamas u\u017eklausos lizdas. Joki\u0173 teisi\u0173 nereikia \u2014 AF_ALG pagal nutyl\u0117jim\u0105 prieinamas bet kuriam vartotojui.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tada kiekvienam 4 bait\u0173 naudingiausios apkrovos fragmentui konstruojama <code>sendmsg()<\/code> + <code>splice()<\/code> pora. AAD perne\u0161a reikiamus 4 baitus (seqno_lo). Splice deskriptorius tiekia <code>\/usr\/bin\/su<\/code> puslapio pod\u0117lio puslapius reikiamu poslinkiu. Parametrai \u2014 <code>assoclen<\/code>, splice ilgis ir poslinkis \u2014 parenkami taip, kad laikinasis \u012fra\u0161ymas pataikyt\u0173 tiksliai \u012f reikiam\u0105 dvejetainio failo .text sekcijos pozicij\u0105.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I\u0161kvietimas <code>recv()<\/code> paleid\u017eia de\u0161ifravim\u0105. <code>authencesn<\/code> viduje vyksta laikinasis \u012fra\u0161ymas \u012f <code>dst[assoclen + cryptlen]<\/code> \u2014 scatterwalk pereina i\u0161 RX buferio \u012f puslapio pod\u0117l\u012f ir \u012fra\u0161o 4 baitus. HMAC tikrinimas i\u0161 karto stringa, <code>recvmsg()<\/code> gr\u0105\u017eina klaid\u0105 \u2014 ta\u010diau \u012fra\u0161ymas \u012fvyko. Kai visi apvalkalo kodo fragmentai sud\u0117lioti, u\u017epuolikas kvie\u010dia <code>execve(\"\/usr\/bin\/su\")<\/code>. Branduolys \u012fkelia dvejetain\u012f fail\u0105 i\u0161 puslapio pod\u0117lio \u2014 kur jau gyvena apvalkalo kodas. Kadangi su yra setuid-root, kodas vykdomas kaip UID 0.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>KAIP KLAIDA I\u0160GYVENO DEVYNERIUS METUS<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u0160ios pa\u017eeid\u017eiamyb\u0117s istorija \u2014 vadov\u0117linis pavyzdys, kaip trys nepriklausomai saug\u016bs pakeitimai sudaro mirtin\u0105j\u012f derin\u012f. 2011 metais \u012f branduol\u012f buvo prid\u0117tas <code>authencesn<\/code> IPsec ESP palaikymui su 64 bit\u0173 sekos numeriais (RFC 4303). Laikinasis \u012fra\u0161ymas \u012f paskirties i\u0161sklaidyt\u0105j\u012f s\u0105ra\u0161\u0105 buvo saugus: susieti duomenys gyveno atskirame i\u0161sklaidytajame s\u0105ra\u0161e, o vienintelis i\u0161kviet\u0117jas buvo vidinis branduolio xfrm sluoksnis.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2015 metais AF_ALG gavo AEAD palaikym\u0105, o <code>authencesn<\/code> buvo perkeltas \u012f nauj\u0105 AEAD s\u0105saj\u0105. Ta\u010diau <code>algif_aead.c<\/code> tuomet veik\u0117 ne vietoje (out-of-place): <code>req-&gt;src<\/code> ir <code>req-&gt;dst<\/code> buvo atskiri i\u0161sklaidytieji s\u0105ra\u0161ai. Puslapio pod\u0117lio puslapiai patekdavo \u012f <code>src<\/code> (tik skaitymui), laikinasis \u012fra\u0161ymas \u0117jo \u012f <code>dst<\/code> (vartotojo bufer\u012f). Vis dar saugu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2017 metais \u012f <code>algif_aead.c<\/code> buvo prid\u0117ta optimizacija \u2014 vietin\u0117s operacijos (commit <code>72548b093ee3<\/code>). AAD ir \u0161ifratekstas buvo kopijuojami \u012f RX bufer\u012f, ta\u010diau \u017eymos puslapiai buvo prijungiami nuoroda per <code>sg_chain()<\/code>, o tada <code>req-&gt;src = req-&gt;dst<\/code>. Puslapio pod\u0117lio puslapiai dabar atsid\u016br\u0117 ra\u0161omame paskirties i\u0161sklaidytajame s\u0105ra\u0161e. <code>authencesn<\/code> laikinasis \u012fra\u0161ymas kirto buferio rib\u0105 ir pateko \u012f juos. Niekas nesusiejo 2017 met\u0173 optimizacijos su 2015 met\u0173 <code>authencesn<\/code> laikinuoju \u012fra\u0161ymu ir to paties laikotarpio splice kelio. Klaida egzistavo trij\u0173 pakeitim\u0173 sankirtos ta\u0161ke \u2014 ir i\u0161liko nematoma beveik de\u0161imtmet\u012f.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>KOD\u0116L RANDA DABAR<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Copy Fail nebuvo rastas klasikiniu aplauzos testavimu ar rankiniu auditu. Taeyang Lee suformulavo hipotez\u0119 \u2014 kad splice() gali tiekti puslapio pod\u0117lio nuorodas \u012f kriptografin\u012f TX i\u0161sklaidyt\u0105j\u012f s\u0105ra\u0161\u0105 \u2014 ir perdav\u0117 j\u0105 Xint Code \u012frankiui su u\u017eduotimi patikrinti vis\u0105 kriptografin\u0119 posistem\u0119 pagal \u0161\u012f \u0161ablon\u0105. Po valandos rezultatuose Copy Fail buvo auk\u0161\u010diausio sunkumo radinys.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tai platesn\u0117s 2026 met\u0173 tendencijos dalis: DI pagalba pagr\u012fsti pa\u017eeid\u017eiamybi\u0173 tyrimai pradeda sistemingai apr\u0117pti atak\u0173 pavir\u0161ius, kurie met\u0173 metus nebuvo tikrinami. Keli\u0173 posistemi\u0173 sankirta \u2014 kriptografija, VFS, lizdo API \u2014 yra b\u016btent tokia vieta, kur \u017emogus auditorius gal\u0117jo lengvai praleisti ry\u0161\u012f tarp pakeitim\u0173, i\u0161sibars\u010diusi\u0173 per skirtingus failus ir metus. Modelis mato vis\u0105 i\u0161kvietim\u0173 graf\u0105 i\u0161 karto ir gali patikrinti konkre\u010di\u0105 hipotez\u0119 per laik\u0105, nepasiekiam\u0105 rankinei analizei.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>LAIKO JUOSTA<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2026 m. kovo 23 d. Taeyang Lee prane\u0161\u0117 apie pa\u017eeid\u017eiamyb\u0119 Linux branduolio saugumo komandai. Kit\u0105 dien\u0105 at\u0117jo patvirtinimas, po dviej\u0173 dien\u0173 \u2014 pataisymas buvo pasi\u016blytas ir per\u017ei\u016br\u0117tas. 2026 m. baland\u017eio 1 d. pataisymas pateko \u012f pagrindin\u012f branduol\u012f (commit <code>a664bf3d603d<\/code>). Baland\u017eio 22 d. buvo priskirtas CVE-2026-31431. Baland\u017eio 29 d. \u2014 vie\u0161as atskleidimas su pilnu techniniu apra\u0161ymu ir koncepcijos \u012frodymo eksploitu copy.fail svetain\u0117je.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Koordinuotas atskleidimas u\u017etruko 37 dienas nuo prane\u0161imo iki paskelbimo \u2014 greitai pagal Linux branduolio standartus. Saugumo komanda per kelias valandas patvirtino kriti\u0161kum\u0105 ir paspartino pataisymo \u012ftraukim\u0105. Distribucij\u0173 branduolio atnaujinimai pasirod\u0117 per kelias dienas po vie\u0161o atskleidimo per \u012fprastus branduolio paketo atnaujinimo kanalus.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>KOD\u0116L TAI SVARBU<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Copy Fail u\u017edaro svarbi\u0105 m\u0105stymo sp\u0105st\u0105: &#8222;failas diske nepasikeit\u0117, vadinasi sistema \u0161vari&#8221;. Vientisumo tikrinimo \u012frankiai, lyginantys kontrolines sumas su disku (AIDE disko tikrinimo re\u017eimu, Tripwire), Copy Fail neaptiks \u2014 nes failas diske tikrai nepasikeit\u0117. Pasikeit\u0117 tik puslapio pod\u0117lis atmintyje, o tai yra tas, i\u0161 ko branduolys realiai vykdo kod\u0105. FIM turi b\u016bti papildytas nenormalaus proceso elgsenos steb\u0117jimu, o ne tik fail\u0173 kontrolin\u0117mis sumomis.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Antrasis svarbus aspektas \u2014 konteineriai. Puslapio pod\u0117lis bendras serveriui ir visiems jame veikiantiems konteineriams. Copy Fail \u2014 tai ne tik LPE: tai konteinerio pab\u0117gimo primitivas. Vienas pa\u017eeistas pod su neprivilegijuotu vartotoju gali gauti root visame Kubernetes mazge, modifikuodamas setuid dvejetain\u012f fail\u0105 bendrame serverio puslapio pod\u0117lyje. Xint paskelb\u0117 antr\u0105 technin\u012f apra\u0161ym\u0105 \u2014 &#8222;From Pod to Host&#8221; \u2014 b\u016btent \u0161iam vektoriui.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Galiausiai devynerius metus nepasteb\u0117ta klaida aktyviai pl\u0117tojamame Linux branduolyje primena: keli\u0173 posistemi\u0173 sankirta yra akliausias audito ta\u0161kas. authencesn, AF_ALG ir splice() \u2014 trys komponentai, kiekvienas tikrintas atskirai. Niekas j\u0173 netikino kartu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ATNAUJINIMAS<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pataisymas at\u0161aukia 2017 met\u0173 optimizacij\u0105: <code>req-&gt;src<\/code> dabar rodo \u012f TX SGL (kuriame gali b\u016bti puslapio pod\u0117lio puslapiai i\u0161 splice), o <code>req-&gt;dst<\/code> \u2014 \u012f RX SGL (vartotojo bufer\u012f). Puslapio pod\u0117lio puslapiai nebepatenka \u012f ra\u0161om\u0105 paskirties i\u0161sklaidyt\u0105j\u012f s\u0105ra\u0161\u0105. Pataisym\u0105 sudaro trys upstream komitai; pagrindinis \u2014 <code>a664bf3d603d<\/code>, kuris pa\u0161alina vietin\u0119 operacij\u0105 i\u0161 <code>algif_aead.c<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Debian ir Ubuntu sistemose prad\u0117kite patikrin\u0119 dabartin\u0119 branduolio versij\u0105 \u2014 \u012fsiminkite i\u0161vest\u012f, kad gal\u0117tum\u0117te patvirtinti, jog po atnaujinimo ji pasikeis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uname -r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tada atnaujinkite ir perkraukite:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt upgrade -y<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Po perkrovimo v\u0117l vykdykite <code>uname -r<\/code> \u2014 versija turi pasikeisti. \u012ediegtas paketas be perkrovimo neapsaugo: sistema toliau veikia su pa\u017eeid\u017eiamu branduoliu atmintyje.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modprobe.d aplinkkelis, paplit\u0119s internete po vie\u0161o atskleidimo, veikia tik Debian ir Ubuntu sistemose. RHEL, AlmaLinux, CloudLinux ir kitose RHEL \u0161eimos distribucijose modulis <code>algif_aead<\/code> sukompiliuotas tiesiai \u012f branduol\u012f ir n\u0117ra atskiras \u012fkeliamas modulis. Komandos vykdomos be klaid\u0173, ta\u010diau nieko nedaro \u2014 ir sukuria klaiding\u0105 saugumo jausm\u0105. Greitas patikrinimas:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>modinfo algif_aead | grep filename<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I\u0161vestis <code>(builtin)<\/code> rei\u0161kia, kad modulis \u012fmontuotas, o modprobe.d aplinkkelis neveiks. Jei rodomas kelias iki <code>.ko<\/code> failo \u2014 modulis \u012fkeliamas ir aplinkkelis suveiks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RHEL \u0161eimos sistemoms, kur negalima nedelsiant atnaujinti, CloudLinux rekomendacijoje apra\u0161ytas veikiantis laikinas aplinkkelis per <code>initcall_blacklist<\/code>. Jis reikalauja perkrovimo, ta\u010diau u\u017edaro atakos pavir\u0161i\u0173 nekei\u010diant branduolio:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo grubby --update-kernel=ALL --args=\"initcall_blacklist=algif_aead_init\"\nsudo reboot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Po perkrovimo patikrinkite, kad parametras aktyvus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo grubby --info=ALL | grep initcall_blacklist<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kai pataisytas branduolys \u012fdiegtas \u2014 pa\u0161alinkite aplinkkel\u012f ir perkraukite dar kart\u0105:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo grubby --update-kernel=ALL --remove-args=\"initcall_blacklist=algif_aead_init\"\nsudo reboot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Svarbu: dm-crypt\/LUKS, kTLS, IPsec, SSH ir standartiniai OpenSSL\/GnuTLS k\u016briniai nepriklauso nuo AF_ALG ir nuo \u0161io aplinkkelio nenukent\u0117s. Paveiktos bus tik programos, tiesiogiai naudojan\u010dios AF_ALG AEAD operacijoms \u2014 tai reta \u012fprastame web serveryje.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>I\u0160VADOS<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Copy Fail yra reta pa\u017eeid\u017eiamyb\u0117, kurioje techninis mechanizmas kartu ir eleganti\u0161kas, ir destruktyvus. Trys kodo eilut\u0117s vienoje funkcijoje, prid\u0117tos kaip optimizacija prie\u0161 devynerius metus, pavert\u0117 standartin\u0119 \u0161ifravimo API \u012frankiu ra\u0161ymui \u012f bet kurio sistemos failo puslapio pod\u0117l\u012f. Rezultatas \u2014 deterministinis root per 732 Python baitus visose pagrindin\u0117se Linux distribucijose.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sistemos administratoriui veiksmas paprastas: atnaujinti branduol\u012f ir perkrauti. Modprobe.d aplinkkelio neliesti, jei esate RHEL \u0161eimoje. Dirbantiems su Kubernetes: Xint antrasis techninis apra\u0161ymas apie konteinerio pab\u0117gim\u0105 per \u0161\u012f primitiv\u0105 jau paskelbtas \u2014 perskaitykite.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Paveiktos branduolio versijos:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Visi Linux branduoliai, i\u0161leisti nuo 2017 iki 2026 m. kovo \u2014 tai yra versijos nuo ~4.14 iki 6.18 imtinai.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Nepaveikti:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Branduoliai senesni nei 2017 m. (iki ~4.14) \u2014 juose nebuvo vietin\u0117s optimizacijos, suk\u016brusios \u0161i\u0105 klaid\u0105. CloudLinux 7 (klasikinis) taip pat nepaveiktas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pataisyta pradedant nuo:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Distribucija<\/th><th>Pirmoji saugi branduolio versija<\/th><\/tr><\/thead><tbody><tr><td>Debian \/ Ubuntu<\/td><td>bet kuris branduolys atnaujintas po 2026 m. baland\u017eio 1 d. \u2014 per apt upgrade<\/td><\/tr><tr><td>RHEL 8 \/ AlmaLinux 8 \/ CL8<\/td><td>4.18.0-553.121.1.el8<\/td><\/tr><tr><td>RHEL 9 \/ AlmaLinux 9 \/ CL9<\/td><td>5.14.0-611.49.2.el9_7<\/td><\/tr><tr><td>RHEL 10 \/ AlmaLinux 10 \/ CL10<\/td><td>6.12.0-124.52.2.el10_1<\/td><\/tr><tr><td>Amazon Linux 2023<\/td><td>per dnf upgrade po 2026 m. baland\u017eio<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Patikrinkite savo versij\u0105:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uname -r<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Theori tyr\u0117jas Taeyang Lee analizavo, kas nutinka, kai Linux kriptografin\u0117 posistem\u0117 per sistemin\u012f i\u0161kvietim\u0105 splice() gauna duomenis tiesiai i\u0161 puslapio pod\u0117lio. Intuicija rod\u0117: jei neprivilegijuotas vartotojas gali pateikti branduolio atmintyje saugom\u0105 failo puslap\u012f \u0161ifravimo operacijai, ka\u017ekas turi nueiti negerai. Jis paleido dirbtinio intelekto \u012frank\u012f Xint Code tikrinti vis\u0105 kriptografinio posistemo kod\u0105, pasiekiam\u0105 i\u0161 vartotojo erdv\u0117s, \u2014 ir ma\u017edaug po valandos ekrane pasirod\u0117 CVE-2026-31431. Copy Fail yra login\u0117 klaida Linux branduolio kriptografiniame \u0161ablone authencesn (CWE-787, ra\u0161ymas u\u017e buferio rib\u0173). Ji leid\u017eia neprivilegijuotam vietiniam vartotojui \u012fra\u0161yti lygiai 4 baitus \u012f bet kurio jam skaitomo failo puslapio pod\u0117l\u012f. Jei taikiniu pasirinksite setuid dvejetain\u012f fail\u0105 \u2014 pavyzd\u017eiui, \/usr\/bin\/su \u2014 tai tiesus kelias \u012f root. CVSS 7.8, High. Koncepcijos \u012frodymo eksploitas paskelbtas 2026 m. baland\u017eio 29 d. ir telpa \u012f 732 Python baitus. Pataisymas jau pagrindin\u0117je branduolio versijoje; distribucijos i\u0161leido atnaujinimus \u012fprastu branduolio paketo mechanizmu. Tai, kas i\u0161skiria Copy Fail i\u0161 kit\u0173 \u0161i\u0173 met\u0173 LPE pa\u017eeid\u017eiamybi\u0173, yra determinizmas. Dirty Cow reikalavo laim\u0117ti lenktyni\u0173 s\u0105lyg\u0105 ir neretai sugriaudavo sistem\u0105 nes\u0117km\u0117s atveju. Dirty Pipe veik\u0117 tik konkre\u010diose branduolio versijose. Copy Fail suveikia be lenktyni\u0173, be pakartojim\u0173, be riziking\u0173 laiko lang\u0173. Tas pats 732 bait\u0173 scenarijus be pakeitim\u0173 suteikia root Ubuntu, Amazon Linux, RHEL ir SUSE \u2014 jokie atskiri poslinkiai kiekvienai distribucijai, jokie perkompiliavimai. 100% patikimumas. KAS YRA AF_ALG IR PUSLAPIO POD\u0116LIS AF_ALG \u2014 tai lizdo tipas, atveriantis branduolio kriptografin\u0119 posistem\u0119 neprivilegijuotai vartotojo erdvei. Sukuriate lizd\u0105, prisiregistruojate prie bet kurio AEAD \u0161ablono (Authenticated Encryption with Associated Data) ir perduodate duomenis \u0161ifravimui ar de\u0161ifravimui. Joki\u0173 teisi\u0173 nereikia \u2014 tai standartin\u0117 funkcija, prieinama bet kuriam vartotojui. Puslapio pod\u0117lis \u2014 tai branduolio atminties sluoksnis, kuriame saugomas fail\u0173 turinys. Kai skaitote fail\u0105, branduolys \u012fkelia jo puslapius \u012f pod\u0117l\u012f. Visos v\u0117lesn\u0117s operacijos read(), mmap() ir execve() dirba su \u0161iuo pod\u0117liu, o ne tiesiogiai su disku. Puslapio pod\u0117lis bendras visai sistemai \u2014 \u012fskaitant visus konteinerius, veikian\u010dius serveryje. Sisteminis i\u0161kvietimas splice() perduoda duomenis tarp fail\u0173 deskriptori\u0173 ir vamzd\u017ei\u0173 be kopijavimo \u2014 perduodama ne turinys, o nuoroda \u012f atminties puslap\u012f. Kai vartotojas daro splice() failo \u012f AF_ALG lizd\u0105, kriptografin\u0117 posistem\u0117 gauna tiesiogines nuorodas \u012f to failo puslapio pod\u0117lio puslapius. Ne kopijas \u2014 lygiai tuos pa\u010dius fizinius puslapius, i\u0161 kuri\u0173 branduolys skaitys fail\u0105 kito execve() metu. KAIP VEIKIA KLAIDA AEAD de\u0161ifravimo per AF_ALG metu \u012fvesties srautas atrodo taip: AAD (susietos autentifikavimo duomenys) || \u0161ifratekstas || autentifikavimo \u017eyma. Kodas faile algif_aead.c nustato operacij\u0105 vietoje (in-place): tas pats i\u0161sklaidytasis s\u0105ra\u0161as (scatterlist) tarnauja ir kaip \u012fvestis, ir kaip i\u0161vestis. AAD ir \u0161ifratekstas kopijuojami i\u0161 TX buferio \u012f RX bufer\u012f per memcpy_sglist. Ta\u010diau \u017eyma \u2014 paskutiniai keli \u012fvesties baitai \u2014 nekopijuojama. Vietoj to puslapio pod\u0117lio puslapiai su \u017eyma prijungiami prie i\u0161vesties i\u0161sklaidytojo s\u0105ra\u0161o per sg_chain(). Galiausiai i\u0161vesties i\u0161sklaidytasis s\u0105ra\u0161as atrodo taip: vartotojo RX buferis || tikslinio failo puslapio pod\u0117lio puslapiai. \u010cia \u012f \u017eaidim\u0105 \u012f\u017eengia authencesn. Tai AEAD apvalkalas IPsec protokolui su i\u0161pl\u0117stini\u0173 sekos numeri\u0173 palaikymu. IPsec 64 bit\u0173 sekos numeris suskaidytas \u012f vyresn\u012fj\u012f pus\u0119 (seqno_hi, AAD baitai 0\u20133) ir jaunesn\u012fj\u012f (seqno_lo, baitai 4\u20137). HMAC skai\u010diavimui authencesn turi perstatyti \u0161iuos baitus \u2014 ir tam naudoja paskirties i\u0161sklaidyt\u0105j\u012f s\u0105ra\u0161\u0105 kaip laikin\u0105 darbo erdv\u0119. Konkre\u010diai: funkcija crypto_authenc_esn_decrypt() vykdo i\u0161kvietim\u0105 scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1) \u2014 4 bait\u0173 \u012fra\u0161ym\u0105 \u012f pozicij\u0105 assoclen + cryptlen, tai yra i\u0161 karto u\u017e autentifikavimo \u017eymos. \u012eprastomis s\u0105lygomis tai b\u016bt\u0173 vartotojo buferio sritis. Ta\u010diau kai \u017eymos puslapiai prijungti per sg_chain() prie i\u0161vesties i\u0161sklaidytojo s\u0105ra\u0161o \u2014 scatterwalk pereina i\u0161 RX buferio tiesiai \u012f tikslinio failo puslapio pod\u0117l\u012f ir \u012fra\u0161o 4 baitus, kuriuos visi\u0161kai kontroliuoja u\u017epuolikas. HMAC tikrinimas stringa, recvmsg() gr\u0105\u017eina klaid\u0105 \u2014 ta\u010diau 4 baitai jau \u012fra\u0161yti. Branduolys nepa\u017eymi puslapio kaip pakeisto, tod\u0117l failas diske lieka nepakeistas. Pakeitimas tik atmintyje \u2014 bet b\u016btent i\u0161 atminties branduolys skaito fail\u0105 execve() metu. KAIP TAI I\u0160NAUDOJAMA U\u017epuolikas visi\u0161kai kontroliuoja tris \u012fra\u0161ymo parametrus: kur\u012f fail\u0105 (bet kur\u012f, skaitom\u0105 dabartiniam vartotojui), koki\u0105 pozicij\u0105 failo viduje (per splice poslinkio, ilgio ir assoclen pasirinkim\u0105), ir koki\u0105 reik\u0161m\u0119 \u012fra\u0161yti (sendmsg AAD baitai 4\u20137). Tai ne atsitiktinis perra\u0161ymas \u2014 tai tikslus, kartojamas, programuojamas savavali\u0161kos reik\u0161m\u0117s \u012fra\u0161ymas \u012f savavali\u0161k\u0105 bet kurio failo puslapio pod\u0117lio pozicij\u0105. Eksploitas nukreiptas \u012f \/usr\/bin\/su \u2014 setuid-root dvejetain\u012f fail\u0105, esant\u012f visose testuotose distribucijose. Pirmiausia atidaromas AF_ALG lizdas ir prisiregistruojama prie \u0161ablono authencesn(hmac(sha256),cbc(aes)). Nustatomas raktas. Priimamas u\u017eklausos lizdas. Joki\u0173 teisi\u0173 nereikia \u2014 AF_ALG pagal nutyl\u0117jim\u0105 prieinamas bet kuriam vartotojui. Tada kiekvienam 4 bait\u0173 naudingiausios apkrovos fragmentui konstruojama sendmsg() + splice() pora. AAD perne\u0161a reikiamus 4 baitus (seqno_lo). Splice deskriptorius tiekia \/usr\/bin\/su puslapio pod\u0117lio puslapius reikiamu poslinkiu. Parametrai \u2014 assoclen, splice ilgis ir poslinkis \u2014 parenkami taip, kad laikinasis \u012fra\u0161ymas pataikyt\u0173 tiksliai \u012f reikiam\u0105 dvejetainio failo .text sekcijos pozicij\u0105. I\u0161kvietimas recv() paleid\u017eia de\u0161ifravim\u0105. authencesn viduje vyksta laikinasis \u012fra\u0161ymas \u012f dst[assoclen + cryptlen] \u2014 scatterwalk pereina i\u0161 RX buferio \u012f puslapio pod\u0117l\u012f ir \u012fra\u0161o 4 baitus. HMAC tikrinimas i\u0161 karto stringa, recvmsg() gr\u0105\u017eina klaid\u0105 \u2014 ta\u010diau \u012fra\u0161ymas \u012fvyko. Kai visi apvalkalo kodo fragmentai sud\u0117lioti, u\u017epuolikas kvie\u010dia execve(&#8222;\/usr\/bin\/su&#8221;). Branduolys \u012fkelia dvejetain\u012f fail\u0105 i\u0161 puslapio pod\u0117lio \u2014 kur jau gyvena apvalkalo kodas. Kadangi su yra setuid-root, kodas vykdomas kaip UID 0. KAIP KLAIDA I\u0160GYVENO DEVYNERIUS METUS \u0160ios pa\u017eeid\u017eiamyb\u0117s istorija \u2014 vadov\u0117linis pavyzdys, kaip trys nepriklausomai saug\u016bs pakeitimai sudaro mirtin\u0105j\u012f derin\u012f. 2011 metais \u012f branduol\u012f buvo prid\u0117tas authencesn IPsec ESP palaikymui su 64 bit\u0173 sekos numeriais (RFC 4303). Laikinasis \u012fra\u0161ymas \u012f paskirties i\u0161sklaidyt\u0105j\u012f s\u0105ra\u0161\u0105 buvo saugus: susieti duomenys gyveno atskirame i\u0161sklaidytajame s\u0105ra\u0161e, o vienintelis i\u0161kviet\u0117jas buvo vidinis branduolio xfrm sluoksnis. 2015 metais AF_ALG gavo AEAD palaikym\u0105, o authencesn buvo perkeltas \u012f nauj\u0105 AEAD s\u0105saj\u0105. Ta\u010diau algif_aead.c tuomet veik\u0117 ne vietoje (out-of-place): req-&gt;src ir req-&gt;dst buvo atskiri i\u0161sklaidytieji s\u0105ra\u0161ai. Puslapio pod\u0117lio puslapiai patekdavo \u012f src (tik skaitymui), laikinasis \u012fra\u0161ymas \u0117jo \u012f dst (vartotojo bufer\u012f). Vis dar saugu. 2017 metais \u012f algif_aead.c buvo prid\u0117ta optimizacija \u2014 vietin\u0117s operacijos (commit 72548b093ee3). AAD ir \u0161ifratekstas buvo kopijuojami \u012f RX bufer\u012f, ta\u010diau \u017eymos puslapiai buvo prijungiami nuoroda per sg_chain(), o tada req-&gt;src = req-&gt;dst. Puslapio pod\u0117lio puslapiai dabar atsid\u016br\u0117 ra\u0161omame paskirties i\u0161sklaidytajame s\u0105ra\u0161e. authencesn laikinasis \u012fra\u0161ymas kirto buferio rib\u0105 ir pateko \u012f juos. Niekas nesusiejo 2017 met\u0173 optimizacijos su 2015 met\u0173 authencesn laikinuoju \u012fra\u0161ymu ir to paties laikotarpio splice kelio. Klaida egzistavo trij\u0173 pakeitim\u0173 sankirtos ta\u0161ke \u2014 ir i\u0161liko nematoma beveik de\u0161imtmet\u012f. KOD\u0116L [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":20504,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[202,199,155],"tags":[469,470,471,472,473,474,328,475,476,477,393,478,479,480,481],"class_list":["post-20508","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cve-lt","category-linux-lt","category-saugumas","tag-af_alg","tag-algif_aead","tag-authencesn","tag-containerescape","tag-copyfail","tag-cve-2026-31431","tag-kubernetes","tag-linuxkernel","tag-lpe","tag-pagecache","tag-patch","tag-privilegeescalation","tag-root","tag-setuid","tag-splice"],"_links":{"self":[{"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/posts\/20508","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/comments?post=20508"}],"version-history":[{"count":3,"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/posts\/20508\/revisions"}],"predecessor-version":[{"id":20516,"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/posts\/20508\/revisions\/20516"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/media\/20504"}],"wp:attachment":[{"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/media?parent=20508"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/categories?post=20508"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysadmin.courses\/lt\/wp-json\/wp\/v2\/tags?post=20508"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}