dmb->cpu_addr was allocated via folio_alloc(). Use folio_put() instead of kfree() in the error exit of ism_alloc_dmb() to avoid slab allocator corruption. While at it, reset dmb->cpu_addr after folio_put to avoid unintentional UAF by future callers.
Unified · Split
| @@ -231,6 +231,7 @@ static void ism_free_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) · 230 unmodified lines | |||
| 231 | dma_unmap_page(&ism->pdev->dev, dmb->dma_addr, dmb->dmb_len, | 231 | dma_unmap_page(&ism->pdev->dev, dmb->dma_addr, dmb->dmb_len, |
| 232 | DMA_FROM_DEVICE); | 232 | DMA_FROM_DEVICE); |
| 233 | folio_put(virt_to_folio(dmb->cpu_addr)); | 233 | folio_put(virt_to_folio(dmb->cpu_addr)); |
| 234 | dmb->cpu_addr = NULL; | ||
| 234 | } | 235 | } |
| 235 | 236 | ||
| 236 | static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) | 237 | static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) |
| @@ -274,7 +275,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) · 37 unmodified lines | |||
| 274 | return 0; | 275 | return 0; |
| 275 | 276 | ||
| 276 | out_free: | 277 | out_free: |
| 277 | kfree(dmb->cpu_addr); | 278 | folio_put(folio); |
| 279 | dmb->cpu_addr = NULL; | ||
| 278 | out_bit: | 280 | out_bit: |
| 279 | clear_bit(dmb->idx, ism->sba_bitmap); | 281 | clear_bit(dmb->idx, ism->sba_bitmap); |
| 280 | return rc; | 282 | return rc; |