From 5cf658c1750515c92ac397ecc90aa2661494f217 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 17 May 2026 03:27:06 +0300 Subject: [PATCH] Kernel: Fix 2 memory pinning bugs If pinning a region succeeded but pushing the region to a vector failed, we would leak the pin preventing the process from cleaning up --- kernel/kernel/Process.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 5a67dded..2f837a71 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1765,12 +1765,13 @@ namespace Kernel TRY(read_from_user(user_message, &message, sizeof(msghdr))); BAN::Vector regions; + TRY(regions.reserve(!!message.msg_name + !!message.msg_control + !!message.msg_iov)); + BAN::ScopeGuard _([®ions] { for (auto* region : regions) region->unpin(); }); - // FIXME: this can leak memory if push to regions fails but pinning succeeded if (message.msg_name) TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_name, message.msg_namelen, true)))); if (message.msg_control) @@ -1778,6 +1779,7 @@ namespace Kernel if (message.msg_iov) { TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), true)))); + TRY(regions.reserve(regions.size() + message.msg_iovlen)); for (int i = 0; i < message.msg_iovlen; i++) TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, true)))); } @@ -1795,6 +1797,8 @@ namespace Kernel TRY(read_from_user(user_message, &message, sizeof(msghdr))); BAN::Vector regions; + TRY(regions.reserve(!!message.msg_name + !!message.msg_control + !!message.msg_iov)); + BAN::ScopeGuard _([®ions] { for (auto* region : regions) region->unpin(); @@ -1807,6 +1811,7 @@ namespace Kernel if (message.msg_iov) { TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), false)))); + TRY(regions.reserve(regions.size() + message.msg_iovlen)); for (int i = 0; i < message.msg_iovlen; i++) TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, false)))); }