programmatūra · 5 min · 14.10.2026

Android 17 libc kļūda sabojā wcscspn un wcspbrk: izstrādātājs disasamblēja libc.so, jo AOSP avots nav publicēts

Android 17 ievietotā C bibliotēka bionic nepareizi apstrādā divas plaši lietotas funkcijas. Septembra laidienā CP3A.260905.009 funkcijas wcscspn() un wcspbrk() uzskata jebkuru rakstzīmi ar kodu virs U+0100 par sakritību, ja meklējamā kopa satur vismaz divas rakstzīmes un visas tās ir zem U+0100. Android 16 šīs funkcijas strādā pareizi.

Kļūdu 12. oktobrī pieteica izstrādātājs ar segvārdu francisdb NDK projekta pieteikumā #2260. Avota koda septembra būvējumam nav, tāpēc viņš disasamblēja funkciju wcscspn no ierīcē ielādētā faila /apex/com.android.runtime/lib64/bionic/libc.so, lai atrastu cēloni.

Ko dara šīs funkcijas

Funkcijas wcscspn un wcspbrk ir standarta C bibliotēkas daļa darbam ar platajām rakstzīmēm (wchar_t). Pirmā atgriež, cik gara ir virknes sākuma daļa, kurā nav nevienas rakstzīmes no dotās kopas. Otrā atrod pirmo rakstzīmi, kas ietilpst kopā. Tās izmanto teksta parsēšanā, piemēram, lai sadalītu virkni pēc atdalītājiem vai pārbaudītu, vai tekstā ir aizliegtas rakstzīmes.

Praktiski tas nozīmē, ka programma, kura meklē divus atdalītājus (teiksim, komatu un semikolu) latviešu, grieķu vai japāņu tekstā, pirmo burtu ar diakritisko zīmi uztver par atdalītāju. Virkne tiek sagriezta nepareizi. Ja rezultātu izmanto bufera garuma aprēķinam, kļūda var novest arī pie atmiņas pārrakstīšanas.

Kas tieši salūzis

bionic implementācija vispirms izveido 256 baitu lielu bool tabulu uz steka un atzīmē tajā meklējamās rakstzīmes. Pēc tam tā iet cauri virknei. Pārbaude apstājas pie pirmās rakstzīmes ar kodu 0x100 vai lielāku, jo skaitīšana to uztver kā trāpījumu, nevis turpina meklēt tālāk. Tā rezultātā wcscspn() atgriež nepareizu garumu un wcspbrk() norāda uz nepareizu pozīciju.

256 baitu tabula var attēlot tikai koda punktus no 0 līdz 255. Platajām rakstzīmēm virs šī diapazona tajā vietas nav. Pareizai implementācijai šādu rakstzīmi vienkārši nevajadzētu atrast kopā un vajadzētu turpināt skenēšanu. bionic tā vietā ārpus diapazona esošo rakstzīmi pieskaita pie trāpījumiem.

francisdb izmēģināja visu diapazonu no U+0100 līdz U+10FFFF. Nepareizu rezultātu atgrieza 1 111 808 koda punkti. Pārbaudei viņš izmantoja NDK r29 un kompilatoru aarch64-linux-android30-clang. Problēma parādās tikai tad, kad meklējamā kopa satur divas vai vairāk rakstzīmes. Ar vienu rakstzīmi kopā bibliotēka iet pa citu koda zaru un atbild pareizi.

Kuras ierīces skar

Pieteikumā minētas trīs ierīces ar dažādiem drošības ielāpu datumiem. Pixel 7 ar septembra būvējumu uzvedas kļūdaini. Pixel 8a ar 2026. gada 5. septembra ielāpu arī atgriež nepareizus rezultātus. Nothing Phone 2 ar 2026. gada 1. augusta ielāpu strādā pareizi, jo tajā vēl darbojas Android 16 bibliotēka. Tātad kļūda ienāca līdz ar pāreju uz Android 17.

Kļūda skar jebkuru lietotni, kas caur NDK izsauc šīs funkcijas uz platajām rakstzīmēm. Rezultāts ir atkarīgs no sistēmas bibliotēkas versijas ierīcē. Pašas lietotnes kods to nemaina. Angļu tekstā bez diakritiskajām zīmēm problēma nav redzama, tāpēc testos to viegli palaist garām.

Kāpēc nācās disasamblēt

Parasti izstrādātājs atvērtu AOSP pirmkodu un pārbaudītu funkcijas kodu. Šoreiz tā nav pieejama. Tāpēc francisdb no ierīces izvilka failu libc.so, atrada tajā funkciju wcscspn un disasamblēja mašīnkodu, lai saprastu, kur skenēšana apstājas par agru. No disasamblējuma kļuva redzama 256 baitu tabula uz steka un pārbaude, kas platās rakstzīmes uztver kā trāpījumu. Tikai pēc tam viņš varēja aprakstīt cēloni pieteikumā.

Publiskie android17-release avoti ir no 2026. gada jūnija (būvējums android-17.0.0_r1), bet skartie būvējumi ir no septembra. Google inženieris ar segvārdu enh-google norādīja, ka arī zars android-latest-release neietver izmaiņas kopš aprīļa. Android 17 QPR1 avots līdz 13. oktobrim nebija publicēts, lai gan tieši tas darbojas uz Pixel ierīcēm.

Cits komentētājs ar segvārdu Zenczykowski jautāja, kur ir Android 17 QPR1 avots, kas jau vairāk nekā mēnesi stabili darbojas uz Pixel. Google 2025. gadā pārcēla Android izstrādi uz iekšējiem zariem un pirmkodu publicē ar nobīdi pēc laidiena. Pieteikumā daži izstrādātāji šo nobīdi vērtē skarbi.

„Kopš Google nolēma slēgt AOSP pirmkodu, ir uzradušās daudzas kļūdas bez jebkāda labojuma,” pieteikumā raksta izstrādātājs Joaquín Vacas Verísimo.

Google atbilde un sekas

enh-google 12. oktobrī apstiprināja, ka kļūda pastāv arī koda jaunākajā versijā. Labojumu plānots pārnest atpakaļ uz izlaistajām versijām, lai samazinātu skarto ierīču skaitu. Izrādījās, ka esošais wcscspn tests bija kļūdains, tāpēc komanda pievienos trūkstošos testus un izlabos salauzto. Google pārstāvis arī aicināja par citām libc vai rīkkopas kļūdām ziņot atsevišķi.

Kļūda jau skāra reālu projektu. Visual Pinball bibliotēka libwinevbs saņēma labojumu pieteikumā #41, kas pilnībā izvairās no wcspbrk izmantošanas un to aizstāj ar vienkāršu ciklu. Labojumu 11. oktobrī iekļāva izstrādātājs jsm174. Nākamajā dienā francisdb to sasaistīja ar NDK pieteikumu un atkārtoja kļūdu uz Pixel 8a.

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