Bosh sahifa Wiki Segmentation

Segmentation

Segmentation — xotirani mantiqiy qismlarga ajratish yoki dasturga tegishli bo‘lmagan xotiraga murojaat natijasidagi xato kontekstida ishlatiladigan tushuncha.

Kompyuter arxitekturasida segmentation address space’ni code, data va stack kabi o‘zgaruvchan o‘lchamdagi segmentlarga bo‘ladi. Zamonaviy operatsion tizimlarda asosiy xotira boshqaruvi ko‘pincha pagingga tayanadi.

Segmentation fault esa process yaroqsiz yoki ruxsatsiz virtual manzilga murojaat qilganda yuz beradigan xatodir.

Xotira segmentlari

Executable process address space’da mantiqiy bo‘limlarga ega.

Keng tarqalgan qismlar:

Bu bo‘limlar har doim hardware segmentation bilan boshqarilishi shart emas. Ular virtual memory mapping sifatida mavjud.

Text segment

Executable instructionlar saqlanadi.

Odatda:

Bir xil executable’ning text sahifalari bir nechta process o‘rtasida bo‘lishilishi mumkin.

Read-only data

String literal va o‘zgarmas konstantalar.

Writable bo‘lmagan mapping xatoli o‘zgartirishni ushlaydi.

Compiler va linker bu bo‘limni alohida yaratadi.

Data segment

Boshlang‘ich qiymatga ega global va static o‘zgaruvchilar.

Misol:

int count = 10;

Executable faylda initial data saqlanadi.

BSS

Boshlang‘ich qiymati nol yoki ko‘rsatilmagan global/static o‘zgaruvchilar.

Executable ichida barcha nol baytlarni saqlash shart emas. Loader memoryni zero-fill qiladi.

Heap

Dynamic allocation uchun o‘sadigan hudud.

malloc, new va runtime allocator heap’dan xotira beradi.

Heap ichki bo‘sh bloklar, metadata va fragmentationga ega bo‘lishi mumkin.

Stack

Function call frame, local variable va return address saqlanadi.

Har thread alohida stack oladi.

Stack chegaradan oshsa guard page orqali segmentation fault yuz berishi mumkin.

Hardware segmentation

Tarixiy x86 real va protected mode’da address:

segment selector + offset

orqali hosil qilingan.

Segment descriptor:

ni belgilagan.

Bu code va data regionlarni ajratishga yordam bergan.

Flat memory model

Zamonaviy 64-bit operatsion tizimlar ko‘pincha flat address model ishlatadi.

Segment base va limitlarning ko‘pi neytral holatda, isolation esa paging orqali bajariladi.

x86-64da FS va GS segmentlari thread-local yoki kernel data uchun maxsus ishlatilishi mumkin.

Segmentation va paging

Jihat Segmentation Paging
Blok hajmi O‘zgaruvchan Bir xil page
Ma’nosi Code, data kabi mantiqiy Fizik/virtual mapping
Fragmentatsiya External bo‘lishi mumkin Internal bo‘lishi mumkin
Zamonaviy OS Cheklangan hardware rol Asosiy mexanizm
Protection Segment permission Page permission

Ikkalasi tarixan birga ishlatilgan.

Segmentation fault

Unix-like tizimda yaroqsiz memory access processga SIGSEGV signalini berishi mumkin.

Sabablar:

  • null pointer;
  • dangling pointer;
  • buffer overflow;
  • stack overflow;
  • read-only memoryga yozish;
  • executable bo‘lmagan page’dan kod bajarish;
  • noto‘g‘ri pointer arithmetic;
  • use-after-free.

Null pointer

Program 0 yoki unga yaqin unmapped manzilga murojaat qiladi.

Misol:

int *p = NULL;
*p = 10;

OS past addresslarni map qilmaslik orqali xatoni tez aniqlaydi.

Buffer overflow

Array chegarasidan tashqariga yozish boshqa object yoki guard page’ga tegadi.

Xato darhol crash qilishi yoki keyinroq heap metadata buzilganda ko‘rinishi mumkin.

Memory-safe til va bounds checking xavfni kamaytiradi.

Use-after-free

Xotira allocatorga qaytarilgandan keyin eski pointer ishlatiladi.

Blok boshqa objectga berilgan bo‘lishi mumkin.

Natija:

Address sanitizer bunday xatoni aniqlashga yordam beradi.

Stack overflow

Cheksiz recursion yoki juda katta local object stack limitdan oshadi.

Guard page access’da fault chiqaradi.

Stack trace chuqur takrorlanuvchi funksiyani ko‘rsatishi mumkin.

Protection fault

Page mavjud, lekin operationga ruxsat yo‘q.

Masalan:

  • read-only page’ga write;
  • NX page’dan execute;
  • user mode’dan kernel page.

CPU page fault exception beradi, kernel processga SIGSEGV yuboradi.

SIGBUS

Har yaroqsiz memory access SIGSEGV bo‘lavermaydi.

Memory-mapped faylning real hajmidan tashqariga murojaat yoki alignment talabi ayrim platformada SIGBUS berishi mumkin.

Signal turi arxitektura va sababga bog‘liq.

Core dump

Segmentation faultda core dump yaratilishi mumkin.

Debugger:

ni tahlil qiladi.

Debug symbol bo‘lsa stack trace tushunarli bo‘ladi.

ASLR

Addresslar har ishga tushishda o‘zgarishi mumkin.

Logdagi raw address source line’ni darhol bermaydi.

Executable build ID va symbol file kerak.

Sanitizer

Development build’da:

  • AddressSanitizer;
  • UndefinedBehaviorSanitizer;
  • MemorySanitizer;
  • Valgrind

xotira xatolarini topishga yordam beradi.

Ular performance overheadga ega va productionda har doim yoqilmaydi.

Security

Memory corruption hujumchi tomonidan control flow’ni egallash uchun ishlatilishi mumkin.

Himoya:

Crashning o‘zi exploitation bo‘lmaganini kafolatlamaydi.

Diagnostika

Segmentation faultda:

tekshiriladi.

Faqat fault yuz bergan qator emas, xotirani avval buzgan joy ham topilishi kerak.

Linker segmentlari

Executable formatda section va segment tushunchalari farq qiladi.

Compiler object faylda .text, .data, .rodata kabi sectionlar yaratadi. Linker ularni loader uchun LOAD segmentlariga birlashtiradi.

Bir segment page permissionga ega:

  • read;
  • write;
  • execute.

readelf kabi vosita executable section va program headerlarini ko‘rsatadi.

Memory map

Process memory map orqali qaysi manzil oralig‘i qaysi fayl yoki regionga tegishli ekanini ko‘rish mumkin.

Unda:

ko‘rsatiladi.

Fault address shu map bilan solishtirilsa, null access, stack guard yoki bo‘shatilgan region aniqlanadi.

Optimization

Compiler optimization functionlarni inline qilishi, variable’ni registerda saqlashi va kod tartibini o‘zgartirishi mumkin. Production core dump source qatoriga to‘liq mos ko‘rinmasligi mumkin.

Build ID va aynan o‘sha binary uchun debug symbol saqlanadi.

Bog‘liq tushunchalar

Memory segment, Paging, Virtual memory, SIGSEGV, Stack, Heap, Buffer overflow, Use-after-free, Core dump, ASLR