Skip to content

Commit 56fccf2

Browse files
rientjesChristoph Hellwig
authored andcommitted
dma-direct: check return value when encrypting or decrypting memory
__change_page_attr() can fail which will cause set_memory_encrypted() and set_memory_decrypted() to return non-zero. If the device requires unencrypted DMA memory and decryption fails, simply free the memory and fail. If attempting to re-encrypt in the failure path and that encryption fails, there is no alternative other than to leak the memory. Fixes: c10f07a ("dma/direct: Handle force decryption for DMA coherent buffers in common code") Signed-off-by: David Rientjes <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 96a539f commit 56fccf2

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

kernel/dma/direct.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size,
158158
{
159159
struct page *page;
160160
void *ret;
161+
int err;
161162

162163
size = PAGE_ALIGN(size);
163164

@@ -210,8 +211,12 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size,
210211
}
211212

212213
ret = page_address(page);
213-
if (force_dma_unencrypted(dev))
214-
set_memory_decrypted((unsigned long)ret, 1 << get_order(size));
214+
if (force_dma_unencrypted(dev)) {
215+
err = set_memory_decrypted((unsigned long)ret,
216+
1 << get_order(size));
217+
if (err)
218+
goto out_free_pages;
219+
}
215220

216221
memset(ret, 0, size);
217222

@@ -230,9 +235,13 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size,
230235
return ret;
231236

232237
out_encrypt_pages:
233-
if (force_dma_unencrypted(dev))
234-
set_memory_encrypted((unsigned long)page_address(page),
235-
1 << get_order(size));
238+
if (force_dma_unencrypted(dev)) {
239+
err = set_memory_encrypted((unsigned long)page_address(page),
240+
1 << get_order(size));
241+
/* If memory cannot be re-encrypted, it must be leaked */
242+
if (err)
243+
return NULL;
244+
}
236245
out_free_pages:
237246
dma_free_contiguous(dev, page, size);
238247
return NULL;

0 commit comments

Comments
 (0)