skaidrojumi · 4 min · 11.07.2026

Linux 7.2 izmet strncpy pēc sešiem gadiem — 362 labojumi, lai aizvērtu vienu kļūdu klasi

Linux 7.2 kodolā vairs nav funkcijas strncpy(). Kees Cook, kurš vada Kernel Self Protection Project, 20. jūnijā iemapoja pēdējos labojumus, kas izņem šo virkņu kopēšanas funkciju no kodola koda. Darbs ilga sešus gadus un prasīja 362 commit no 70 izstrādātājiem.

strncpy pastāv C valodā kopš 1970. gadiem, un Linux kodolā tā gadiem bija kļūdu avots. Problēma nav pašā uzdevumā — kopēt virkni ar garuma ierobežojumu — bet uzvedībā, ko lielākā daļa programmētāju negaida. Phoronix ziņo, ka ar šo iemapošanu no koda pazuda arī pēdējās atsevišķo procesoru arhitektūru strncpy implementācijas.

Kāpēc strncpy bija bīstama

strncpy negarantē, ka rezultāts beigsies ar NUL baitu. Ja avota virkne ir tikpat gara vai garāka par norādīto limitu, funkcija nokopē n baitus un beigu nulli vairs nepieliek. Kods, kas pēc tam nolasa šo buferi kā C virkni, turpina lasīt aiz bufera robežas blakus esošajā kodola atmiņā, līdz uzduras nulles baitam. Tur var būt kriptogrāfiskas atslēgas, akreditācijas dati vai jebkas cits, kas gadījies tuvumā. Pati kodola dokumentācija šo uzvedību apzīmēja par bīstamu.

Otra nepatikšana ir veiktspēja. Ja avota virkne ir īsāka par buferi, strncpy aizpilda visu atlikušo vietu ar nullēm. 10 zīmju resursdatora nosaukums 256 baitu buferī nozīmē 246 lieki ierakstītus nulles baitus. Uz miljardiem ierīču, kas darbina Linux, šis liekais darbs summējas.

Kods, kas nolasa nepareizi beigtu buferi kā virkni, aizsūta tālāk to, kas atmiņā gadījies blakus. Trūkstošā beigu nulle tāpēc rada veselu atmiņas noplūdes kļūdu klasi.

Kāpēc sešus gadus, ne sešas dienas

Iemesls, kāpēc funkciju nevarēja izmest ar vienu labojumu, ir semantisks. Dažādās kodola vietās strncpy tika lietota piecām atšķirīgām darbībām, katrai ar savu beigu nulles un aizpildes prasību. Vienā vietā vajadzēja NUL-beigtu virkni, citā apzināti izmantoja aizpildi ar nullēm, bet trešā strādāja ar fiksēta platuma binārā protokola laukiem, kur beigu nulle vispār salauztu darbību.

Tas nozīmēja, ka katru izsaukuma vietu vajadzēja saprast atsevišķi. Komanda ar semantisko labošanas rīku Coccinelle atrada tos šablonus, ko varēja aizvietot automātiski, bet neparastās vietas prasīja roku darbu un apkārtējās loģikas pārrakstīšanu. Google inženieris Justin Stitt viens pats uzrakstīja 211 no 362 commit, ejot cauri kodolam apakšsistēmu pēc apakšsistēmas.

Piecas funkcijas vienas vietā

Vecā strncpy zem viena nosaukuma slēpa piecas dažādas nozīmes. Tagad izstrādātājam jāizvēlas pēc tā, ko tiešām vajag:

  • strscpy — nokopē virkni ar garantētu beigu nulli un neaizpilda pārējo;
  • strscpy_pad — tas pats, bet ar nullēm aizpilda atlikušo vietu;
  • strtomem_pad — kopē virkni uz fiksēta izmēra atmiņas apgabalu ar aizpildi;
  • memcpy_and_pad — kopē baitus un aizpilda atlikumu;
  • memcpy — vienkārša baitu kopēšana bez virknes semantikas.

Katra izsaukuma vieta tagad pati pasaka savu nolūku. Kods, ko iepriekš vajadzēja lasīt uzmanīgi, lai saprastu, vai rezultāts vispār ir derīga virkne, tagad to pasaka ar funkcijas vārdu.

Tagad to sargā kompilators

Pēdējais solis padara noteikumu neizbēgamu: jebkurš kodola kods, kas mēģina izsaukt strncpy, vairs nekompilējas. Ieteikums pārvērtās par kompilatora piespiestu politiku, un jaunas problemātiskas vietas kodolā vairs neiekļūs neatkarīgi no tā, cik uzmanīgs bijis recenzents.

Šī nav pirmā šāda tīrīšana. 2024. gada janvārī kodols pēc atsevišķas vairāku gadu kampaņas atbrīvojās no strlcpy, kurai bija savas problēmas ar visas avota virknes skenēšanu pirms kopēšanas. Abas kampaņas vada Kernel Self Protection Project ar mērķi izņemt funkcijas, kuru nosaukums sola drošību, bet uzvedība to grauj.

strncpy izņemšana iekļauta Linux 7.2 apvienošanas logā. Linux 7.2-rc1 iznāca 28. jūnijā, stabilā versija gaidāma augusta beigās, un ar to kodola pirmkods jau pārsniedza 43 miljonus rindu. Tajā pašā logā ienāca AMD HDMI 2.1 Fixed Rate Link atbalsts un post-kvantu ML-DSA parakstu atbalsts IMA un EVM apakšsistēmās. strncpy tīrīšana prasīja sešus gadus roku darba pie koda, kas sācies pirms 30 gadiem.

Avoti

komentārisaruna

Komentāri

Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.

Pievieno komentāru

Tavs e-pasts netiks publicēts. Obligātie lauki atzīmēti.

vēl no skaidrojumisaistītie