Bosh sahifa Wiki Buffer underflow

Buffer underflow

Buffer underflow — dastur buferning haqiqiy boshlanishidan oldingi xotirani o‘qishi yoki yozishi natijasida yuzaga keladigan chegara xatosidir. U ko‘pincha indeksni kamaytirish, manfiy siljishni unsigned songa aylantirish yoki buferda mavjud elementlar sonini noto‘g‘ri hisoblash sababli paydo bo‘ladi. Natija dastur ishdan chiqishi, begona ma’lumot o‘qilishi yoki qo‘shni xotiraning buzilishi bo‘lishi mumkin.

Paydo bo‘lish mexanizmi

Bufer manzili base, uzunligi length bo‘lsa, qonuniy indekslar odatda 0 dan length - 1 gacha bo‘ladi. Kod index - 1 ni hisoblab, index nol ekanini tekshirmasa, manzil buferdan oldinga emas, orqaga siljiydi. C va C++ kabi tillarda bunday pointer arifmetikasi avtomatik chegaraviy tekshiruvga ega emas.

Ring buffer, parser va dekoderlarda “oldingi bayt” yoki “oldingi element”ga murojaat ko‘p uchraydi. Masalan, satr boshidagi escape belgini tekshirish uchun input[pos - 1] ishlatilsa, pos == 0 holati alohida ko‘rilishi shart. Teskari siklda unsigned hisoblagichni nolga yetgach yana kamaytirish juda katta qiymat hosil qiladi.

O‘qish va yozish holatlari

Under-read buferdan oldingi xotirani o‘qiydi. Bu ma’lumot keyinchalik javob, jurnal yoki xato xabariga chiqarilsa, maxfiy qiymatlar sizishi mumkin. Under-write esa buferdan oldingi obyekt, allocator metama’lumoti yoki boshqaruv maydonini o‘zgartiradi. Yozish holati odatda og‘irroq, chunki u dastur oqimiga ta’sir qiladigan buzilish yaratishi mumkin.

Buffer underflow atamasi ba’zan oqimli tizimda iste’molchi ma’lumotni ishlab chiqaruvchidan tezroq olishi natijasida bufer bo‘sh qolishini ham anglatadi. Audio uzatishda bu uzilish yoki jimlik sifatida seziladi. Bu semantik holat xotira chegarasidan oldin murojaat qilishdan farq qiladi; hujjatda qaysi ma’no nazarda tutilgani aniq ko‘rsatiladi.

Aniqlash vositalari

AddressSanitizer ajratilgan blok atrofiga himoya zonalari joylashtirib, chap tomondagi chegaradan chiqishni aniq stack trace bilan topadi. UndefinedBehaviorSanitizer ayrim noto‘g‘ri arifmetik va konversiya holatlarini ko‘rsatadi. Fuzzing nol uzunlik, bir baytli kirish, kesilgan paket va manfiy mantiqiy siljish kabi chekka qiymatlarni sinaydi.

Statik tahlil indeksning qayerdan kelgani, qanday tekshiruvdan o‘tgani va pointerga qachon qo‘shilganini kuzatadi. Testlar faqat odatiy ma’lumot bilan cheklanmay, bo‘sh bufer, birinchi element, oxirgi element va noto‘g‘ri e’lon qilingan uzunlikni ham qamrab oladi.

Oldini olish

Har bir murojaatdan oldin indeksning quyi va yuqori chegarasi tekshiriladi. Teskari sikl sharti unsigned qiymatning nol ostiga o‘tmasligini ta’minlaydigan shaklda yoziladi. Slice, span va bounds-check qiluvchi konteyner pointer bilan uzunlikni birga saqlab, xato ehtimolini kamaytiradi.

Parserda joriy pozitsiya va qolgan baytlar yagona yordamchi funksiya orqali boshqarilishi foydali. Hajm hisoblari overflow va underflowga tekshiriladi, tashqi manbadan kelgan offset esa ishonchli deb qabul qilinmaydi. Xato topilganda faqat bitta ifoda emas, shu indeksni hosil qilgan barcha yo‘llar va o‘xshash call site’lar ko‘rib chiqiladi.

Chegaraviy arifmetika

offset - header_size kabi ifodada ikkala operand unsigned bo‘lsa, kichik offset manfiy natija o‘rniga juda katta musbat son beradi. Tekshiruv ayirishdan keyin emas, undan oldin offset >= header_size shaklida bajariladi. Pointerga offset qo‘shishdan avval uning buffer uzunligidan oshmasligi ham tekshiriladi. C tilidagi size_t manfiy bo‘lmagani uchun index >= 0 sharti doim rost bo‘lishi mumkin. Compiler warninglarni xato sifatida ko‘rish va signed/unsigned konversiyani aniq yozish bunday muammoni erta topadi.

Bog‘liq tushunchalar

Buffer overflow, Out-of-bounds read, Pointer arithmetic, AddressSanitizer, Integer underflow, Ring buffer