CVE-2024-53111
Təsvir
Linux kernel-də aşağıdakı zəiflik aradan qaldırılmışdır: mm/mremap: move_page_tables() funksiyasında ünvanın dövr etməsi (wraparound) problemi düzəldildi 32-bit platformalarda, əgər `len + old_addr` ifadəsi dövr edərsə, `len + old_addr < old_end` şərtinin yanlış şəkildə doğru (false-positive) olması mümkündür. `old_addr`, səhifə cədvəli girişlərinin köçürüldüyü köhnə diapazonun kursorudur; beləliklə, əməliyyat uğurlu olubsa, `old_addr` köhnə bölgənin sonudur və ona `len` dəyərinin əlavə edilməsi dövrə səbəb ola bilər. Bu daşma (overflow), mremap()-in PTE-lərin köçürüldüyünü səhvən düşünməsinə səbəb olur; nəticədə mremap() prosesi dayandırır, lakin yeni VMA xəritədən çıxarılmazdan (unmapped) əvvəl PTE-ləri geri qaytarmır ki, bu da həmin bölgədəki anonim səhifələrin itirilməsinə gətirib çıxarır. Beləliklə, istifadəçi sahəsi (userspace) private-anon bölgəsini mremap() etməyə çalışdıqda və bu xətaya rastladıqda, mremap() xəta qaytaracaq və private-anon bölgəsinin məzmunu sıfırlanmış kimi görünəcəkdir. Həmin yoxlamanın məqsədi odur ki, `old_end - len` orijinal başlanğıc ünvanıdır və yoxlamanı bu formada yazmaq onu daha oxunaqlı edir; buna görə də müqayisəni müvafiq şəkildə yenidən quraraq yoxlama düzəldilmişdir. (Alternativ həll yolu olaraq, "orig_old_start" kimi bir dəyişən tətbiq etməklə bu funksiyanı refaktor etmək mümkün idi.) 32-bit X86 nüvəli VM-də sınaqdan keçirilmişdir; yamasız versiya: ``` user@horn:~/big_mremap$ cat test.c #define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> #include <err.h> #include <sys/mman.h> #define ADDR1 ((void*)0x60000000) #define ADDR2 ((void*)0x10000000) #define SIZE 0x50000000uL int main(void) { unsigned char *p1 = mmap(ADDR1, SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED_NOREPLACE, -1, 0); if (p1 == MAP_FAILED) err(1, "mmap 1"); unsigned char *p2 = mmap(ADDR2, SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED_NOREPLACE, -1, 0); if (p2 == MAP_FAILED) err(1, "mmap 2"); *p1 = 0x41; printf("first char is 0x%02hhx\n", *p1); unsigned char *p3 = mremap(p1, SIZE, SIZE, MREMAP_MAYMOVE|MREMAP_FIXED, p2); if (p3 == MAP_FAILED) { printf("mremap() failed; first char is 0x%02hhx\n", *p1); } else { printf("mremap() succeeded; first char is 0x%02hhx\n", *p3); } } user@horn:~/big_mremap$ gcc -static -o test test.c user@horn:~/big_mremap$ setarch -R ./test first char is 0x41 mremap() failed; first char is 0x00 ``` Yama ilə: ``` user@horn:~/big_mremap$ setarch -R ./test first char is 0x41 mremap() succeeded; first char is 0x41 ```
Necə düzəltmək olar
- linux linux_kernel6.11.10 və ya daha yeni versiya
Təsirlənən məhsullar
| Məhsul | Təsirlənən versiyalar | Düzəldildiyi versiya |
|---|---|---|
| linux linux_kernel | 6.7 ≤ v < 6.11.10, 6.12 | 6.11.10 |
Versiyanızı yoxlayın
Məhsulu seçin və istifadə etdiyiniz versiyanı yazın; versiyanın təsirlənən aralıqda olub-olmadığını görün.
Attack Surface Management
Domenlərinizə bağlı aktivləri, onlarda işləyən texnologiyaları və məlum zəiflikləri bir siyahıda görün.