🔒 Fix potential memory exhaustion in socket reads (#59)

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>
This commit is contained in:
Tarasov Aleksandr
2026-04-17 13:56:29 +03:00
committed by GitHub
parent 5367a3daae
commit 70c7e3789b
3 changed files with 13 additions and 3 deletions
+2 -2
View File
@@ -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<dyn Error>> {
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
+2
View File
@@ -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,
+9 -1
View File
@@ -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<Response, Box<dyn Error +
}
let response_len = u32::from_le_bytes(len_bytes) as usize;
if response_len > 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());