Skip to content

Commit 674ed56

Browse files
tiwaigregkh
authored andcommitted
ALSA: memalloc: Don't exceed over the requested size
commit dfef01e150824b0e6da750cacda8958188d29aea upstream. snd_dma_alloc_pages_fallback() tries to allocate pages again when the allocation fails with reduced size. But the first try actually *increases* the size to power-of-two, which may give back a larger chunk than the requested size. This confuses the callers, e.g. sgbuf assumes that the size is equal or less, and it may result in a bad loop due to the underflow and eventually lead to Oops. The code of this function seems incorrectly assuming the usage of get_order(). We need to decrease at first, then align to power-of-two. Reported-and-tested-by: he, bo <[email protected]> Reported-by: zhang jun <[email protected]> Cc: <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 323cb0f commit 674ed56

File tree

1 file changed

+2
-6
lines changed

1 file changed

+2
-6
lines changed

sound/core/memalloc.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,16 +239,12 @@ int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
239239
int err;
240240

241241
while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) {
242-
size_t aligned_size;
243242
if (err != -ENOMEM)
244243
return err;
245244
if (size <= PAGE_SIZE)
246245
return -ENOMEM;
247-
aligned_size = PAGE_SIZE << get_order(size);
248-
if (size != aligned_size)
249-
size = aligned_size;
250-
else
251-
size >>= 1;
246+
size >>= 1;
247+
size = PAGE_SIZE << get_order(size);
252248
}
253249
if (! dmab->area)
254250
return -ENOMEM;

0 commit comments

Comments
 (0)