Π‘Π»Π΅Π΄ΠΎΠΌ Π·Π° ΠΎΡΠΊΡΡΡΡΠΌ ΠΏΠΈΡΡΠΌΠΎΠΌ Ρ ΠΈΠ·Π²ΠΈΠ½Π΅Π½ΠΈΡΠΌΠΈ Π³ΡΡΠΏΠΏΠ° ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ ΠΈΠ· Π£Π½ΠΈΠ²Π΅ΡΡΠΈΡΠ΅ΡΠ° ΠΠΈΠ½Π½Π΅ΡΠΎΡΡ, ΠΏΡΠΈΡΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² ΡΠ΄ΡΠΎ Linux ΠΎΡ ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ» Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ ΠΡΠ΅Π³ΠΎΠΌ ΠΡΠΎΠ°-Π₯Π°ΡΡΠΌΠ°Π½ΠΎΠΌ, ΡΠ°ΡΠΊΡΡΠ»Π° Π΄Π΅ΡΠ°Π»ΡΠ½ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ± ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½Π½ΡΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ ΡΠ΄ΡΠ° ΠΏΠ°ΡΡΠ°Ρ ΠΈ ΡΠ²ΡΠ·Π°Π½Π½ΡΡ Ρ ΡΡΠΈΠΌΠΈ ΠΏΠ°ΡΡΠ°ΠΌΠΈ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠΊΡ Ρ ΠΌΡΠΉΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°ΠΌΠΈ.
ΠΡΠΈΠΌΠ΅ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎ, ΡΡΠΎ Π²ΡΠ΅ ΠΈΠ· ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ½ΡΡ ΠΏΠ°ΡΡΠ΅ΠΉ Π±ΡΠ»ΠΈ ΠΎΡΠ²Π΅ΡΠ³Π½ΡΡΡ ΠΏΠΎ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΈΠ²Π΅ ΠΌΡΠΉΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ², Π½ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΠ°ΡΡΠ΅ΠΉ Π½Π΅ Π±ΡΠ» ΠΎΠ΄ΠΎΠ±ΡΠ΅Π½. Π£ΠΊΠ°Π·Π°Π½Π½ΡΠΉ ΡΠ°ΠΊΡ Π΄Π°ΡΡ ΠΏΠΎΠ½ΡΡΡ, ΠΏΠΎΡΠ΅ΠΌΡ ΠΡΠ΅Π³ ΠΡΠΎΠ°-Π₯Π°ΡΡΠΌΠ°Π½ ΠΏΠΎΡΡΡΠΏΠΈΠ» ΡΡΠΎΠ»Ρ ΠΆΡΡΡΠΊΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π½Π΅ΠΏΠΎΠ½ΡΡΠ½ΠΎ ΠΊΠ°ΠΊ ΠΏΠΎΡΡΡΠΏΠΈΠ»ΠΈ Π±Ρ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΠΈ, Π΅ΡΠ»ΠΈ Π±Ρ ΠΏΠ°ΡΡΠΈ Π±ΡΠ»ΠΈ ΠΎΠ΄ΠΎΠ±ΡΠ΅Π½Ρ ΠΌΡΠΉΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°ΠΌΠΈ. ΠΠ°Π΄Π½ΠΈΠΌ ΡΠΈΡΠ»ΠΎΠΌ ΠΎΠ½ΠΈ ΡΡΠ²Π΅ΡΠΆΠ΄Π°Π»ΠΈ, ΡΡΠΎ Π½Π°ΠΌΠ΅ΡΠ΅Π²Π°Π»ΠΈΡΡ ΡΠΎΠΎΠ±ΡΠΈΡΡ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ΅ ΠΈ Π½Π΅ Π΄ΠΎΠΏΡΡΡΠΈΠ»ΠΈ Π±Ρ ΠΏΠΎΡΡΡΠΏΠ»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΡΡΠ΅ΠΉ Π² Git, Π½ΠΎ Π½Π΅ΠΏΠΎΠ½ΡΡΠ½ΠΎ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΠΏΠΎΡΡΡΠΏΠΈΠ»ΠΈ Π±Ρ Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ ΠΈ Π½Π°ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄Π°Π»Π΅ΠΊΠΎ ΠΌΠΎΠ³Π»ΠΈ Π·Π°ΠΉΡΠΈ.
ΠΡΠ΅Π³ΠΎ Π² Π°Π²Π³ΡΡΡΠ΅ 2020 Π³ΠΎΠ΄Π° Ρ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΡΡ Π°Π΄ΡΠ΅ΡΠΎΠ² [email protected] ΠΈ [email protected] (ΠΏΠΈΡΡΠΌΠΎ ΠΎΡ ΠΠΆΠ΅ΠΉΠΌΡΠ° ΠΠΎΠ½Π΄Π°) Π±ΡΠ»ΠΎ ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΎ ΠΏΡΡΡ ΠΏΠ°ΡΡΠ΅ΠΉ: Π΄Π²Π° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΡ (1, 2) ΠΈ ΡΡΠΈ Π²ΠΊΠ»ΡΡΠ°ΡΡΠΈΡ ΡΠΊΡΡΡΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ (1, 2, 3), ΡΠΎΠ·Π΄Π°ΡΡΠΈΠ΅ ΡΡΠ»ΠΎΠ²ΠΈΡ Π΄Π»Ρ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠ΅ΠΉ. ΠΠ°ΠΆΠ΄ΡΠΉ ΠΏΠ°ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°Π» Π²ΡΠ΅Π³ΠΎ 1-4 ΡΡΡΠΎΠΊΠΈ ΠΊΠΎΠ΄Π°. ΠΡΠ½ΠΎΠ²Π½Π°Ρ ΠΈΠ΄Π΅Ρ ΠΎΡΠΈΠ±ΠΎΡΠ½ΡΡ ΠΏΠ°ΡΡΠ΅ΠΉ Π±ΡΠ»Π° Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΡΠ΅ΡΠΊΠΈ ΠΏΠ°ΠΌΡΡΠΈ ΠΌΠΎΠΆΠ΅Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΡΠ»ΠΎΠ²ΠΈΠ΅ ΠΏΠΎΡΠ²Π»Π΅Π½ΠΈΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ ΠΈΠ·-Π·Π° Π΄Π²ΠΎΠΉΠ½ΠΎΠ³ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ. ΠΠ΅Π΄Π΅Π»Ρ ΡΠΏΡΡΡΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ ΡΠ΄ΡΠ° Π±ΡΠ»ΠΎ ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½Π° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Ρ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΠΎΠ±ΡΡΠ΄ΠΈΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΡΠΎΠ΄Π²ΠΈΠΆΠ΅Π½ΠΈΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠ΅ΠΉ ΠΏΠΎΠ΄ Π²ΠΈΠ΄ΠΎΠΌ ΡΡΠΈΠ²ΠΈΠ°Π»ΡΠ½ΡΡ ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ ΡΡΠ΅ΡΠ΅ΠΊ ΠΏΠ°ΠΌΡΡΠΈ, Π½ΠΎ ΠΏΡΠΎ ΡΠ°Π½Π΅Π΅ ΠΏΡΠ΅Π΄ΠΏΡΠΈΠ½ΡΡΡΠ΅ ΠΏΠΎΠΏΡΡΠΊΠΈ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Π²ΡΠ΅Π΄ΠΎΠ½ΠΎΡΠ½ΡΡ ΠΏΠ°ΡΡΠ΅ΠΉ Π½ΠΈΡΠ΅Π³ΠΎ ΡΠΊΠ°Π·Π°Π½ΠΎ Π½Π΅ Π±ΡΠ»ΠΎ.
ΠΠ΅ΡΠ²ΡΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ½ΡΠΉ ΠΏΠ°ΡΡ ΡΡΡΡΠ°Π½ΡΠ» ΡΡΠ΅ΡΠΊΡ ΠΏΠ°ΠΌΡΡΠΈ, Π΄ΠΎΠ±Π°Π²Π»ΡΡ Π²ΡΠ·ΠΎΠ² kfree() ΠΏΠ΅ΡΠ΅Π΄ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ, Π½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Π» ΡΡΠ»ΠΎΠ²ΠΈΡ Π΄Π»Ρ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΊ ΠΎΠ±Π»Π°ΡΡΠΈ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΠΎΡΠ»Π΅ Π΅Ρ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΡ (use-after-free). Π£ΠΊΠ°Π·Π°Π½Π½ΡΠΉ ΠΏΠ°ΡΡ Π±ΡΠ» ΠΎΡΠ²Π΅ΡΠ³Π½ΡΡ ΡΠΎΠΏΡΠΎΠ²ΠΎΠΆΠ΄Π°ΡΡΠΈΠΌ (Jiri Slaby), ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠ» Π½Π°Π»ΠΈΡΠΈΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΈ ΡΠΊΠ°Π·Π°Π», ΡΡΠΎ Π³ΠΎΠ΄ Π½Π°Π·Π°Π΄ ΠΊΡΠΎ-ΡΠΎ ΡΠΆΠ΅ ΠΏΡΡΠ°Π»ΡΡ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈΡΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΠ½ΠΎ Π±ΡΠ»ΠΎ Π²Π½Π°ΡΠ°Π»Π΅ ΠΏΡΠΈΠ½ΡΡΠΎ, Π½ΠΎ ΠΏΠΎΡΠΎΠΌ ΠΎΡΠ±ΡΠΎΡΠ΅Π½ΠΎ ΠΏΠΎΡΠ»Π΅ Π²ΡΡΠ²Π»Π΅Π½ΠΈΡ ΡΡΠ»ΠΎΠ²ΠΈΠΉ ΠΏΠΎΡΠ²Π»Π΅Π½ΠΈΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ. > p2 = p1[n] = kmalloc_array(64, sizeof(u16), GFP_KERNEL); > — if (!p2) return -ENOMEM; > + if (!p2) { > + kfree(p1); > + return -ENOMEM; > + }
ΠΡΠΎΡΠΎΠΉ ΠΏΠ°ΡΡ ΡΠ°ΠΊΠΆΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°Π» ΡΡΠ»ΠΎΠ²ΠΈΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ use-after-free. Π£ΠΊΠ°Π·Π°Π½Π½ΡΠΉ ΠΏΠ°ΡΡ Π½Π΅ Π±ΡΠ» ΠΏΡΠΈΠ½ΡΡ ΡΠΎΠΏΡΠΎΠ²ΠΎΠΆΠ΄Π°ΡΡΠΈΠΌ (Dan Carpenter), ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΡΠΊΠ»ΠΎΠ½ΠΈΠ» ΠΏΠ°ΡΡ ΠΈΠ·-Π·Π° Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡΠ΅ΠΉ Π΄ΡΡΠ³ΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ list_add_tail, Π½ΠΎ Π½Π΅ ΠΎΠ±ΡΠ°ΡΠΈΠ» Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠΎ, ΡΡΠΎ Π² ΡΡΠ½ΠΊΡΠΈΠΈ put_device ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄ΡΠ½ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ «chdev», ΠΊΠΎΡΠΎΡΡΠΉ Π½ΠΈΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² Π²ΡΠ·ΠΎΠ²Π΅ dev_err(&chdev->dev..). Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΏΠ°ΡΡ Π½Π΅ Π±ΡΠ» ΠΏΡΠΈΠ½ΡΡ, Ρ ΠΎΡΡ ΠΈ ΠΏΠΎ ΠΏΡΠΈΡΠΈΠ½Π΅, Π½Π΅ ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠΉ Ρ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡΡ. if (ret < 0) { + put_device(&chdev->dev); dev_err(&chdev->dev, DRV_NAME «: kfifo_alloc failed\n»); ret = -ENOMEM; goto err_fifo;
Π’ΡΠ΅ΡΠΈΠΉ ΠΏΠ°ΡΡ ΡΠ°ΠΊΠΆΠ΅ Π½Π΅ Π±ΡΠ» ΠΏΡΠΈΠ½ΡΡ ΠΌΡΠΉΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠΌ (Miquel Raynal) ΠΈΠ·-Π·Π° Π½Π°Π»ΠΈΡΠΈΡ Π΄ΡΡΠ³ΠΎΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ, Π½Π΅ ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠΉ Ρ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡΡ (Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ Π²ΡΠ·ΠΎΠ² put Π΄Π»Ρ pdev). if (!window->virt) { printk(KERN_ERR MOD_NAME «: ioremap(%08lx, %08lx) failed\n», window->phys, window->size); + pci_dev_put(pdev); goto out; } … if (!map) { printk(KERN_ERR MOD_NAME «: kmalloc failed»); + pci_dev_put(pdev); goto out; } memset(map, 0, sizeof(*map)); … if (mtd_device_register(map->mtd, NULL, 0)) { map_destroy(map->mtd); map->mtd = NULL; + pci_dev_put(pdev); goto out; }
ΠΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ, ΡΡΠΎ ΠΈΠ·Π½Π°ΡΠ°Π»ΡΠ½ΠΎ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π»ΠΎΡΡ, ΡΡΠΎ 4 ΠΈΠ· 5 ΠΏΠ°ΡΡΠ΅ΠΉ ΠΈΠΌΠ΅ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, Π½ΠΎ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΠΈ ΡΠ°ΠΌΠΈ Π΄ΠΎΠΏΡΡΡΠΈΠ»ΠΈ ΠΎΡΠΈΠ±ΠΊΡ ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ½ΠΎΠΌ, ΠΏΠΎ ΠΈΡ
ΠΌΠ½Π΅Π½ΠΈΡ, ΠΏΠ°ΡΡΠ΅ Π±ΡΠ»ΠΎ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΎ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠ΅ ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅, Π±Π΅Π· Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌΡΡ
ΡΡΠ»ΠΎΠ²ΠΈΠΉ Π΄Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΠΎΡΠ»Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΡ. err = pci_request_mem_regions(pdev, nitrox_driver_name); if (err) { pci_disable_device(pdev); + dev_err(&pdev->dev, «Failed to request mem regions!\n»); return err; }
ΠΡΡΠΎΡΠ½ΠΈΠΊ: opennet.ru