Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Multiprocessing - Concurrency - Parallel computing - Parallelism
- Xilinx üzərind test etdiyim vulnerable kernel driver (Xilinx FPGA) rutini.
- TOCTTOU - Time of use to Time of check.
- vulnerable piece;
- //DMA(Direct memory access) mapped edilmiş adresleri user space-den 0_0.
- if (copy_from_user(dma_addr, dma_ptr, sizeof(buf) && copy_from_user(dma_count, addr_count, sizeof(dma_count)))
- return -EFAULT;
- if(dma_count > 0x100)
- return;
- mgb = kzalloc(dma_count,GFP_KERNEL);
- memcpy(mgb, dma_addr, dma_count) < =========== double fetch
- Burada vulnerability race condition qarşının alınmamasıdır. Multitasking depended proses/thread paralel və yaxud concurrent icra edilə bilər. Bu halda proseslər və yaxud thread-lər arasında
- scheduling edildiyinə görə "thread 0" tərəfindən təyin edilən dma_count resursu critical section-a yerləşdirilmir (locking, mutex və s.). Daha sonra dma_count "thread 1" tərəfindən modifikasiya edilə bilir. Bu halda da DMA area üçün
- "thread 0" müraciətinə görə ayrılmış ərazi sayı (dma_count) 0x100 olur. İkinci thread concurrent çalışdıqda (preemption) "thread 0" preempt edilir və context switching baş verir yəni scheduler "thread 1" icra etməyə başlayır və bizim hazırladığımız "thread 1" üzərində dma_count dəyərini modifikasiya edə bilərik.
- Bu halda
- Time of check stage:
- branch 1 - if (copy_from_user(dma_addr, dma_ptr, sizeof(buf) && copy_from_user(dma_count, addr_count, sizeof(dma_count)))
- branch 2 - if(dma_count > 0x100)
- Time of use stage:
- memcpy(mgb, dma_addr, dma_count) < =========== double fetch
- Artıq bu stage-də dma_count dəyərini thread 1 tərəfindən dəyişir bilərik "dma_count = 0x1000"
- Time slice scheduling
- ICT 0 (instruction context thread 0)
- ICT 1 (instruction context thread 1)
- P (Preemption)
- Time
- -------------------------------------------------------
- |ICT 0|ICT 1|ICT 1|ICT 0|ICT 0|ICT 1|ICT 0|ICT 1|
- -------------------------------------------------------
- P P P P P P P P P
- Əlimdəki Xilinx üzərində test etməyə başladım linux üzərində preemtable thread-lər yaratdım. Bu halda da time sharing scheduling istifadə edilir deyə context switching-də
- dma_count dəyərini schedule edilən thread 1 tərəfindən modifikasiya etmə imkanım oldu.
- Graph
- | mov edx, [ebp - dma_ptr] |
- | mov ebi, [ebp - dma_addr]|
- | push ecx |
- | push edx |
- | push edi |
- | call copy_from_user |
- | test eax, eax |
- |
- ---------------------------->
- |
- | cmp ecx,0x100 |
- | jg 0x42700410 |
- |
- |
- / \
- <-------------------- ----------------------->
- | |
- | mov edx, GFP_KERNEL | | mov esp,ebp |
- | push edx | | pop ebp |
- | push ecx | | ret |
- | call kzalloc |
- |
- |
- \
- -------------------------->
- |
- | mov ebx, [ebp - dma_addr] | Thread 1 (CPU 0)
- | mov edx, [eax] | | context switching |
- | push ecx | // < ------Thread 0 preempt----------| mov [ecx], 0x10000 |
- | push ebx | // < ----- Thread 1 execute----------| ret |
- | push edx |
- | call memcpy | //overflow
- Kernel thread 1-i schedule edir və bu thread dma_count dəyərini dəyişir daha sonra digər thread schedule edildikdə dəyər 0x10000 olduğundan overflow baş verir.
- - "Hərşeyin üstü ;)" -
- aka metaizm rockzz :)
Advertisement
Add Comment
Please, Sign In to add comment