programmatūra · 6 min · 21.07.2026

Linux 7.2 izmet strncpy pēc sešu gadu darba — 362 ielāpi likvidē kļūdaino funkciju

Linux 7.2 izstrādes zarā ir pievienots ielāps, kas no kodola pirmkoda pilnībā izņem funkciju strncpy(). Aiz šī viena soļa stāv 362 ielāpi, ap 70 līdzautoru un seši gadi darba. strncpy() bija viens no ilgstošākajiem atmiņas kļūdu avotiem Linux kodolā, un tagad tā no koda pazūd.

Izmaiņas nonāca 7.2 kokā 20. jūnijā. Kopš tā brīža jebkurš mēģinājums izsaukt strncpy() jaunā kodola kodā vairs netiek kompilēts — būvējums izgāžas. Funkcija C valodas standartbibliotēkā pastāv kopš 1970. gadiem, un daudzus gadus programmētāji to izmantoja virkņu kopēšanai, domādami, ka tā ir drošā izvēle.

Kāpēc strncpy bija bīstama

Problēma slēpjas tajā, ko strncpy() dara, kad avota virkne ir garāka par norādīto garumu. Tādā gadījumā funkcija nokopē tieši norādīto baitu skaitu un neieliek beigās nullbaitu (NUL). Rezultāts ir virkne bez noslēguma. Nākamā koda daļa, kas šo buferi nolasa kā parastu C virkni, turpina lasīt aiz tās robežas — cauri blakus esošajai kodola atmiņai, līdz nejauši uzduras kādam nullbaitam.

Kodola buferī blakus var atrasties jutīgi dati. Tā rodas atmiņas noplūdes kļūdu klase, kur programma atklāj baitus, kuriem tai nevajadzēja piekļūt. Otra strncpy() problēma ir vienkāršāka: ja avota virkne ir īsāka par bufera izmēru, funkcija atlikušo daļu piepilda ar nullēm līdz pašam galam. Lielam buferim tas nozīmē lieku CPU darbu katrā izsaukumā.

Klasiskais nepareizais paraugs izskatās gandrīz droši: strncpy(dst, src, sizeof(dst)). Ja src aizpilda visu dst, izbeidzošā nulle vairs neietilpst, un buferis paliek bez tās. Tieši šī nianse gadu gaitā ir pievīlusi daudzus autorus, jo strncpy nosaukums liek domāt par drošu, garuma ierobežotu kopiju.

Funkciju nevarēja izņemt ar vienu automātisku aizvietošanu. Katrs izsaukums bija jāsaprot atsevišķi — vai konkrētajā vietā ir vajadzīga nullbaita izbeigšana, vai fiksēta platuma lauks, vai vienkārša atmiņas kopija.

362 ielāpi un seši gadi

Tieši šī prasība saprast katru izsaukuma vietu atsevišķi izskaidro, kāpēc tīrīšana ilga tik ilgi. Kodola koks satur tūkstošiem virkņu kopēšanas vietu, un neviens skripts nevar zināt, kāds bija sākotnējā autora nodoms. Tāpēc darbs sadalījās 362 atsevišķos ielāpos, ko sešu gadu laikā iesniedza aptuveni 70 dažādu izstrādātāju, kā apkopo Phoronix.

Katrai strncpy() vietai bija jāizvēlas piemērots aizstājējs no kodola drošāko funkciju kopas:

  • strscpy() — kad rezultātam vajag garantētu nullbaita izbeigšanu;
  • strscpy_pad() — tas pats, bet ar nullēm papildinātu atlikumu;
  • strtomem_pad() — fiksēta platuma laukiem, kur nullbaits nav vajadzīgs;
  • memcpy() vai memcpy_and_pad() — kad kopējamo baitu skaits jau ir zināms.

Ar 7.2 strncpy() pazūd no kodola iekšējām galvenēm pavisam. Funkcija jau iepriekš bija ierakstīta kodola dokumentācijas sarakstā ar novecojušām saskarnēm, bet tikai tagad tās izmantošana tiek bloķēta kompilācijas līmenī.

Kas vēl ienāk Linux 7.2

Tajā pašā izstrādes logā ienāca arī Cache-Aware Scheduling. Šo plānotāja uzlabojumu vairāk nekā gadu izstrādāja Intel inženieri, un tā ideja ir turēt uzdevumus, kas dala kopīgus datus, viena pēdējā līmeņa keša (LLC) domēnā. Kad uzdevumi paliek pie sava keša, procesoram retāk jāgaida dati no lēnākas atmiņas. Testos ar MongoDB slodzi šī izmaiņa deva jūtamu ātruma pieaugumu.

No aparatūras puses 7.2 spēj ielādēties uz Apple M3 Mac datoriem, kaut atbalsts pagaidām ir minimāls — sistēma nonāk līdz konsolei, bet ne tālāk. AMDGPU draiveris saņem pirmo HDMI 2.1 FRL atbalstu. x86 procesoriem laika zīmoga skaitītājs (TSC) kļūst par cietu prasību, kas ļauj izmest veco koda ceļu tiem retajiem procesoriem, kuriem tā nebija. Vienlaikus kodols atsakās no dažiem seniem AMD čipiem: K5 procesoriem, Elan sistēmām uz čipa un Geode atbalsta.

Izstrādes logu aizvēra 7.2-rc1. Christian Brauner strādāja pie failu sistēmas slāņa, Ingo Molnar un Thomas Gleixner pie plānotāja un slēgšanas mehānismiem, Jens Axboe un Steven Rostedt pie bloku rindām un izsekošanas. Aptuveni trešdaļa no visa ielāpa ir AMD GPU reģistru definīcijas.

Ko tas maina izstrādātājiem

Praktiskā sekas ir tieša: kodola koda autoram, kurš pieradis rakstīt strncpy(dst, src, sizeof(dst)), tagad jāizvēlas strscpy() vai kāds no radniecīgajiem izsaukumiem. Vecais kods, kas jau bija iekšā, ir pārrakstīts sešu gadu laikā; jaunam kodam kompilators vairs neļaus atgriezties pie kļūdainā ieraduma.

Solis iekļaujas plašākā kodola virzienā uz atmiņas drošību. Pēdējos gados kodolā ir izmests virkne bīstamu C konstrukciju, ir ieviesta buferu robežu pārbaude kompilācijas laikā, un jaunu koda daļu arvien biežāk raksta Rust valodā. strncpy() izņemšana ir viena no lielākajām atsevišķajām šī darba daļām, jo funkcija bija tik dziļi iesakņojusies vecajā kodā.

Ārpus kodola strncpy() lietotāja telpas programmās paliek — C standarts to nekur nav izņēmis. Linux izmaiņa attiecas tikai uz kodola pirmkodu, kur atmiņas noplūde no bufera nozīmē tiešu drošības risku. Stabilā 7.2 versija gaidāma pēc vairākiem laidiena kandidātiem tuvākajos mēnešos.

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 programmatūrasaistītie