From e3094f898b298fcc9ad4b691206f80a18e7a33f8 Mon Sep 17 00:00:00 2001 From: Johannes Leupolz Date: Thu, 18 Dec 2025 21:36:13 +0000 Subject: [PATCH] Fix potential race --- docs/DESIGN.md | 1 + vuinputd/src/cuse_device/vuinput_ioctl.rs | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 04f91ba..fdeee78 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -481,6 +481,7 @@ Under these constraints, post-exec namespace switching provides a robust and pre at the time of `fork()`, the child process may block forever on its first allocation, including implicit allocations inside libc or Rust runtime code. See also [https://github.com/rust-lang/rust/blob/c1e865c/src/libstd/sys/unix/process.rs#L202 + and https://systemd.io/ARCHITECTURE/ . The chosen approach offers the best balance between correctness, portability, and operational simplicity. diff --git a/vuinputd/src/cuse_device/vuinput_ioctl.rs b/vuinputd/src/cuse_device/vuinput_ioctl.rs index 3793cba..6d8d49d 100644 --- a/vuinputd/src/cuse_device/vuinput_ioctl.rs +++ b/vuinputd/src/cuse_device/vuinput_ioctl.rs @@ -198,6 +198,7 @@ pub unsafe extern "C" fn vuinput_ioctl( .dispatch(Box::new(mknod_job)); awaiter(&jobs::mknod_device_in_container_job::State::Finished); debug!("fh {}: mknod_device in container has been finished ", fh); + fuse_lowlevel::fuse_reply_ioctl(_req, 0, std::ptr::null(), 0); // we do not wait for the udev stuff let emit_udev_event_job = EmitUdevEventInContainerJob::new( @@ -213,13 +214,9 @@ pub unsafe extern "C" fn vuinput_ioctl( .lock() .unwrap() .dispatch(Box::new(emit_udev_event_job)); + } else { + fuse_lowlevel::fuse_reply_ioctl(_req, 0, std::ptr::null(), 0); } - - // write a SYN-event (which is just zeros) just for validation - let syn_event: [u8; 24] = [0; 24]; - vuinput_state.file.write_all(&syn_event).unwrap(); - - fuse_lowlevel::fuse_reply_ioctl(_req, 0, std::ptr::null(), 0); } UI_DEV_DESTROY => { debug!("fh {}: ioctl UI_DEV_DESTROY", fh);