CVE-2023-52478
Təsvir
Linux kernelində aşağıdakı zəiflik həll edilmişdir: HID: logitech-hidpp: Qəbuledici USB-dən ayrıldıqda kernelin çökməsini düzəlt hidpp_connect_event() özü ilə yarışdıqda *dörd* yoxlama vaxtı ilə istifadə vaxtı (TOCTOU) yarışına malikdir. hidpp_connect_event() əsasən iş növbəsindən (workqueue) işləyir, lakin o, həmçinin probe() zamanı da işləyir və əgər probe()-dan hidpp_connect_event() işlədən thread aparat üzərində gözləyərkən aparat tərəfindən "device-connected" paketi alınarsa, o zaman iş növbəsindən hidpp_connect_event() işlədən ikinci thread başladılacaq. Bu, aşağıdakı yarışlara yol açır (qeyd edin ki, aşağıdakı kod sadələşdirilmişdir): 1. Protokolun alınması + çap edilməsi (zərərsiz yarış): if (!hidpp->protocol_major) { hidpp_root_get_protocol_version() hidpp->protocol_major = response.rap.params[0]; } Biz əslində bu yarışın rhbz#2227968-ə əlavə edilmiş abrt çıxışındakı dmesg-də baş verdiyini görə bilərik: [ 3064.624215] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected. [ 3064.658184] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected. Əlavə logging ilə test göstərmişdir ki, bundan sonra 2 thread növbə ilə aparat giriş mutexini (send_mutex) tutur, beləliklə onlar bütün digər TOCTOU hallarından keçərək hamısına çatırlar: 2. Adın HIDPP adına yenilənməsi (zərərsiz yarış): if (hidpp->name == hdev->name) { ... hidpp->name = new_name; } 3. Batareya üçün power_supply sinfinin işə salınması (problemli!): hidpp_initialize_battery() { if (hidpp->battery.ps) return 0; probe_battery(); /* Bloklanır, threadlər növbə ilə bunu icra edir */ hidpp->battery.desc.properties = devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL); hidpp->battery.ps = devm_power_supply_register(&hidpp->hid_dev->dev, &hidpp->battery.desc, cfg); } 4. Gecikdirilmiş input_device-in yaradılması (potensial problemli): if (hidpp->delayed_input) return; hidpp->delayed_input = hidpp_allocate_input(hdev); Burada həqiqətən böyük problem 3-dür. Yarışa düşmək aşağıdakı ardıcıllığa gətirib çıxarır: hidpp->battery.desc.properties = devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL); hidpp->battery.ps = devm_power_supply_register(&hidpp->hid_dev->dev, &hidpp->battery.desc, cfg); ... hidpp->battery.desc.properties = devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL); hidpp->battery.ps = devm_power_supply_register(&hidpp->hid_dev->dev, &hidpp->battery.desc, cfg); Beləliklə, indi biz eyni batareya üçün 2 power supply qeydiyyatdan keçirmişik, bu istifadəçi məkanı baxımından bir qədər qəribə görünür, lakin bu, hətta ən böyük problem deyil. Diqqət yetirin ki: 1. Bütün bunlar devm ilə idarə olunur 2. hidpp->battery.desc strukturu 2 power supply arasında paylaşılır 3. hidpp->battery.desc.properties ikinci devm_kmemdup() nəticəsinə işarə edir Bu, qəbuledicinin USB-dən ayrılması zamanı istifadədən sonra azad etmə (use after free) ssenarisinə səbəb olur: 1. Sonuncu qeydiyyatdan keçmiş power supply sinif cihazı qeydiyyatdan çıxarılır 2. Sonuncu devm_kmemdup() çağırışından olan yaddaş azad edilir, hidpp->battery.desc.properties indi azad edilmiş yaddaşa işarə edir 3. Birinci qeydiyyatdan keçmiş power supply sinif cihazı qeydiyyatdan çıxarılır, bu istifadəçi məkanına remove uevent göndərilməsini əhatə edir, hansı ki uevent məlumatlarını doldurmaq üçün power_supply_uevent()-i çağırır 4. power_supply_uevent() indi azad edilmiş yaddaşa işarə edən hidpp->battery.desc.properties-dən istifadə edir və bu, buna bənzər backtrace-lərə gətirib çıxarır: Sep 22 20:01:35 eric kernel: BUG: unable to handle page fault for address: ffffb2140e017f08 ... Sep 22 20:01:35 eric kernel: Workqueue: usb_hub_wq hub_event Sep 22 20:01:35 eric kernel: RIP: 0010:power_supply_uevent+0xee/0x1d0 ... Sep 22 20:01:35 eric kernel: ? asm_exc_page_fault+0x26/0x30 Sep 22 20:01:35 eric kernel: ? power_supply_uevent+0xee/0x1d0 Sep 22 20:01:35 eric kernel: ? power_supply_uevent+0x10d/0x1d0 Sep 22 20:01:35 eric kernel: dev_uevent+0x10f/0x2d0 Sep 22 20:01:35 eric kernel: kobject_uevent_env+0x291/0x680 Sep 22 20:01:35 eric kernel: ---truncated---
Necə düzəltmək olar
- linux linux_kernel4.14.328, 4.19.297, 5.4.259, 5.10.199, 5.15.136, 6.1.59, 6.5.8 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 | v < 4.14.328, 4.15 ≤ v < 4.19.297, 4.20 ≤ v < 5.4.259, 5.5 ≤ v < 5.10.199, 5.11 ≤ v < 5.15.136, 5.16 ≤ v < 6.1.59, 6.2 ≤ v < 6.5.8, 6.6 | 4.14.328, 4.19.297, 5.4.259, 5.10.199, 5.15.136, 6.1.59, 6.5.8 |
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.