# P2-logd.patch # Extract logd hardening: optional kernel debug/syslog handles, graceful error # handling, and resilient request processing loop. # # Files: logd/src/main.rs, logd/src/scheme.rs diff --git a/logd/src/main.rs b/logd/src/main.rs index 3636f1fa..559d8993 100644 --- a/logd/src/main.rs +++ b/logd/src/main.rs @@ -6,18 +6,30 @@ use crate::scheme::LogScheme; mod scheme; fn daemon(daemon: daemon::SchemeDaemon) -> ! { - let socket = Socket::create().expect("logd: failed to create log scheme"); + let socket = match Socket::create() { + Ok(s) => s, + Err(e) => { + eprintln!("logd: failed to create log scheme: {e}"); + std::process::exit(1); + } + }; let mut scheme = LogScheme::new(&socket); let handler = Blocking::new(&socket, 16); let _ = daemon.ready_sync_scheme(&socket, &mut scheme); - libredox::call::setrens(0, 0).expect("logd: failed to enter null namespace"); - - handler - .process_requests_blocking(scheme) - .expect("logd: failed to process requests"); + if let Err(e) = libredox::call::setrens(0, 0) { + eprintln!("logd: failed to enter null namespace: {e}"); + } + + match handler.process_requests_blocking(scheme) { + Ok(never) => match never {}, + Err(e) => { + eprintln!("logd: failed to process requests: {e}"); + std::process::exit(1); + } + } } fn main() { diff --git a/logd/src/scheme.rs b/logd/src/scheme.rs index 070de3d6..ef3e175c 100644 --- a/logd/src/scheme.rs +++ b/logd/src/scheme.rs @@ -22,7 +22,7 @@ pub enum LogHandle { pub struct LogScheme<'sock> { socket: &'sock Socket, - kernel_debug: File, + kernel_debug: Option, output_tx: Sender, handles: HandleMap, } @@ -34,12 +34,24 @@ enum OutputCmd { impl<'sock> LogScheme<'sock> { pub fn new(socket: &'sock Socket) -> Self { - let kernel_debug = OpenOptions::new() + let kernel_debug = match OpenOptions::new() .write(true) .open("/scheme/debug") - .unwrap(); + { + Ok(f) => Some(f), + Err(e) => { + eprintln!("logd: failed to open /scheme/debug: {e}"); + None + } + }; - let mut kernel_sys_log = std::fs::File::open("/scheme/sys/log").unwrap(); + let kernel_sys_log = match std::fs::File::open("/scheme/sys/log") { + Ok(f) => Some(f), + Err(e) => { + eprintln!("logd: failed to open /scheme/sys/log: {e}"); + None + } + }; let (output_tx, output_rx) = mpsc::channel::(); @@ -72,20 +84,28 @@ impl<'sock> LogScheme<'sock> { } }); - let output_tx2 = output_tx.clone(); - std::thread::spawn(move || { - let mut handle_buf = vec![]; - let mut buf = [0; 4096]; - buf[.."kernel: ".len()].copy_from_slice(b"kernel: "); - loop { - let n = kernel_sys_log.read(&mut buf["kernel: ".len()..]).unwrap(); - if n == 0 { - // FIXME currently possible as /scheme/log/kernel presents a snapshot of the log queue - break; + if let Some(mut kernel_sys_log) = kernel_sys_log { + let output_tx2 = output_tx.clone(); + std::thread::spawn(move || { + let mut handle_buf = vec![]; + let mut buf = [0; 4096]; + buf[.."kernel: ".len()].copy_from_slice(b"kernel: "); + loop { + let n = match kernel_sys_log.read(&mut buf["kernel: ".len()..]) { + Ok(n) => n, + Err(e) => { + eprintln!("logd: error reading kernel log: {e}"); + break; + } + }; + if n == 0 { + // FIXME currently possible as /scheme/log/kernel presents a snapshot of the log queue + break; + } + Self::write_logs(&output_tx2, &mut handle_buf, "kernel", &buf, None); } - Self::write_logs(&output_tx2, &mut handle_buf, "kernel", &buf, None); - } - }); + }); + } LogScheme { socket, @@ -120,9 +140,9 @@ impl<'sock> LogScheme<'sock> { let _ = kernel_debug.flush(); } - output_tx - .send(OutputCmd::Log(mem::take(handle_buf))) - .unwrap(); + if let Err(e) = output_tx.send(OutputCmd::Log(mem::take(handle_buf))) { + eprintln!("logd: failed to send log output: {e}"); + } } i += 1; @@ -196,7 +216,7 @@ impl<'sock> SchemeSync for LogScheme<'sock> { handle_buf, context, buf, - Some(&mut self.kernel_debug), + self.kernel_debug.as_mut(), ); Ok(buf.len()) @@ -217,7 +237,10 @@ impl<'sock> SchemeSync for LogScheme<'sock> { ) { return Err(e); } - self.output_tx.send(OutputCmd::AddSink(new_fd)).unwrap(); + if let Err(e) = self.output_tx.send(OutputCmd::AddSink(new_fd)) { + eprintln!("logd: failed to add log sink: {e}"); + return Err(Error::new(EIO)); + } Ok(1) }