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:
- readable;
- executable;
- writable emas.
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:
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.
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:
- NX;
- ASLR;
- stack canary;
- control-flow protection;
- safe allocator;
- memory-safe language;
- sandbox;
- compiler hardening.
Crashning o‘zi exploitation bo‘lmaganini kafolatlamaydi.
Diagnostika
Segmentation faultda:
- aniq signal;
- fault address;
- stack trace;
- core dump;
- source line;
- pointer lifecycle;
- input;
- optimization;
- thread race;
- sanitizer;
- mapping permission
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:
- executable;
- shared library;
- heap;
- stack;
- anonymous mapping;
- permission
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