summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkleines Filmröllchen <filmroellchen@serenityos.org>2022-06-15 21:35:02 +0200
committerLinus Groh <mail@linusgroh.de>2022-06-23 23:26:33 +0100
commitf6af357763a13fe7d1f2a8997dae8004796c430a (patch)
treea016d8ab8af137cee56ebdefaac4a4025766b3aa
parent07d712ea00d400a46c7480bcb4825590fb4c29c1 (diff)
downloadserenity-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.cpp8
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;