diff options
author | kleines Filmröllchen <filmroellchen@serenityos.org> | 2022-06-15 21:35:02 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-06-23 23:26:33 +0100 |
commit | f6af357763a13fe7d1f2a8997dae8004796c430a (patch) | |
tree | a016d8ab8af137cee56ebdefaac4a4025766b3aa | |
parent | 07d712ea00d400a46c7480bcb4825590fb4c29c1 (diff) | |
download | serenity-f6af357763a13fe7d1f2a8997dae8004796c430a.zip |
Kernel/Audio: Fix buffer size underflow for non-page-aligned sizes
When the size of the audio data was not a multiple of a page size,
subtracting the page size from this unsigned variable would underflow it
close to 2^32 and be clamped to the page size again. This would lead to
writes into garbage addresses because of an incorrect write size,
interestingly only causing the write() call to error out.
Using saturating math neatly fixes this problem and allows buffer
lengths that are not a multiple of a page size.
-rw-r--r-- | Kernel/Devices/Audio/AC97.cpp | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/Kernel/Devices/Audio/AC97.cpp b/Kernel/Devices/Audio/AC97.cpp index 70326df7e4..85c5dda52b 100644 --- a/Kernel/Devices/Audio/AC97.cpp +++ b/Kernel/Devices/Audio/AC97.cpp @@ -207,12 +207,12 @@ ErrorOr<size_t> AC97::write(size_t channel_index, UserOrKernelBuffer const& data m_buffer_descriptor_list = TRY(MM.allocate_dma_buffer_pages(buffer_descriptor_list_size, "AC97 Buffer Descriptor List"sv, Memory::Region::Access::Write)); } - auto remaining = length; + Checked<size_t> remaining = length; size_t offset = 0; - while (remaining > 0) { - TRY(write_single_buffer(data, offset, min(remaining, PAGE_SIZE))); + while (remaining > static_cast<size_t>(0)) { + TRY(write_single_buffer(data, offset, min(remaining.value(), PAGE_SIZE))); offset += PAGE_SIZE; - remaining -= PAGE_SIZE; + remaining.saturating_sub(PAGE_SIZE); } return length; |