From 70c7e3789bd2978680df6ea93142b5013ee6e3b9 Mon Sep 17 00:00:00 2001 From: Tarasov Aleksandr <55220741+arabianq@users.noreply.github.com> Date: Fri, 17 Apr 2026 13:56:29 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20Fix=20potential=20memory=20exhau?= =?UTF-8?q?stion=20in=20socket=20reads=20(#59)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses a security vulnerability where the daemon or client could be forced to allocate up to 10MB of memory per malformed socket message, potentially leading to Out-Of-Memory (OOM) crashes. Changes: - Introduced a central `MAX_MESSAGE_SIZE` constant of 128KB in `src/types/socket.rs`. - Enforced the 128KB limit on incoming requests in `src/bin/daemon.rs`. - Enforced the 128KB limit on incoming responses in `src/utils/daemon.rs`. - Preserved detailed `eprintln!` logging when messages are rejected. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- src/bin/daemon.rs | 4 ++-- src/types/socket.rs | 2 ++ src/utils/daemon.rs | 10 +++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/bin/daemon.rs b/src/bin/daemon.rs index 057dacf..c874716 100644 --- a/src/bin/daemon.rs +++ b/src/bin/daemon.rs @@ -1,5 +1,5 @@ use pwsp::{ - types::socket::{Request, Response}, + types::socket::{Request, Response, MAX_MESSAGE_SIZE}, utils::{ commands::parse_command, daemon::{ @@ -109,7 +109,7 @@ async fn commands_loop(listener: UnixListener) -> Result<(), Box> { let request_len = u32::from_le_bytes(len_bytes) as usize; - if request_len > 10 * 1024 * 1024 { + if request_len > MAX_MESSAGE_SIZE { eprintln!( "Failed to read message from client: request too large ({} bytes)!", request_len diff --git a/src/types/socket.rs b/src/types/socket.rs index 769901c..307c4e6 100644 --- a/src/types/socket.rs +++ b/src/types/socket.rs @@ -1,6 +1,8 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; +pub const MAX_MESSAGE_SIZE: usize = 128 * 1024; + #[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Request { pub name: String, diff --git a/src/utils/daemon.rs b/src/utils/daemon.rs index f2c67a2..6635324 100644 --- a/src/utils/daemon.rs +++ b/src/utils/daemon.rs @@ -2,7 +2,7 @@ use crate::{ types::{ audio_player::AudioPlayer, config::DaemonConfig, - socket::{Request, Response}, + socket::{Request, Response, MAX_MESSAGE_SIZE}, }, utils::pipewire::{create_link, get_device}, }; @@ -135,6 +135,14 @@ pub async fn make_request(request: Request) -> Result MAX_MESSAGE_SIZE { + eprintln!( + "Failed to read response from daemon: response too large ({} bytes)!", + response_len + ); + return Err("Response too large".into()); + } + let mut buffer = vec![0u8; response_len]; if stream.read_exact(&mut buffer).await.is_err() { return Err("Failed to read response".into());