From 552ab12f3013c5ac89d9cde9713aa078232351cf Mon Sep 17 00:00:00 2001 From: Johannes Leupolz Date: Thu, 18 Dec 2025 21:25:53 +0000 Subject: [PATCH] Fix tests. Mknod in bubblewrap is not possible if it was not bind-mounted without a nodev flag. --- vuinputd-tests/src/bwrap.rs | 13 +++++++++++++ vuinputd-tests/tests/integration_tests.rs | 3 +-- vuinputd/src/cuse_device/vuinput_ioctl.rs | 5 +---- .../src/jobs/emit_udev_event_in_container_job.rs | 5 +---- vuinputd/src/jobs/mknod_device_in_container_job.rs | 11 +++-------- vuinputd/src/jobs/mod.rs | 2 +- vuinputd/src/jobs/remove_from_container_job.rs | 4 +--- vuinputd/src/process_tools/mod.rs | 2 +- 8 files changed, 22 insertions(+), 23 deletions(-) diff --git a/vuinputd-tests/src/bwrap.rs b/vuinputd-tests/src/bwrap.rs index 17e7065..2514fee 100644 --- a/vuinputd-tests/src/bwrap.rs +++ b/vuinputd-tests/src/bwrap.rs @@ -100,6 +100,19 @@ impl BwrapBuilder { self } + pub fn dev(mut self) -> Self { + // for our tests, we cannot simply use the "--dev"-flag, because it creates a tmpfs with the nodev flag + // see SETUP_MOUNT_DEV and PRIV_SEP_OP_TMPFS_MOUNT + // in https://github.com/containers/bubblewrap/blob/v0.11.0/bubblewrap.c#L1370-L1376 . + // So, we mount a temporary directory that does not have this restrictions. + self.args.extend([ + "--dev-bind".into(), + "/dev/tmp/vuinputd-test".into(), + "/dev".into(), + ]); + self + } + pub fn tmpfs(mut self, path: &str) -> Self { self.args.push("--tmpfs".into()); self.args.push(path.into()); diff --git a/vuinputd-tests/tests/integration_tests.rs b/vuinputd-tests/tests/integration_tests.rs index 400e667..ed39e08 100644 --- a/vuinputd-tests/tests/integration_tests.rs +++ b/vuinputd-tests/tests/integration_tests.rs @@ -134,8 +134,7 @@ fn test_keyboard_in_container_with_vuinput() { .ro_bind("/", "/") .tmpfs("/tmp") // dev needs to be writable for the new devices - .tmpfs("/dev") - .tmpfs("/dev/input") + .dev() // run needs to be writable for the udev devices .tmpfs("/run") .dev_bind("/dev/vuinput-test", "/dev/uinput") diff --git a/vuinputd/src/cuse_device/vuinput_ioctl.rs b/vuinputd/src/cuse_device/vuinput_ioctl.rs index e61bf22..3793cba 100644 --- a/vuinputd/src/cuse_device/vuinput_ioctl.rs +++ b/vuinputd/src/cuse_device/vuinput_ioctl.rs @@ -197,10 +197,7 @@ pub unsafe extern "C" fn vuinput_ioctl( .unwrap() .dispatch(Box::new(mknod_job)); awaiter(&jobs::mknod_device_in_container_job::State::Finished); - debug!( - "fh {}: mknod_device in container has been finished ", - fh - ); + debug!("fh {}: mknod_device in container has been finished ", fh); // we do not wait for the udev stuff let emit_udev_event_job = EmitUdevEventInContainerJob::new( diff --git a/vuinputd/src/jobs/emit_udev_event_in_container_job.rs b/vuinputd/src/jobs/emit_udev_event_in_container_job.rs index a3af1ed..fe74777 100644 --- a/vuinputd/src/jobs/emit_udev_event_in_container_job.rs +++ b/vuinputd/src/jobs/emit_udev_event_in_container_job.rs @@ -14,10 +14,7 @@ use async_io::Timer; use log::debug; use crate::{ - actions::{ - action::Action, - runtime_data::{read_udev_data}, - }, + actions::{action::Action, runtime_data::read_udev_data}, job_engine::job::{Job, JobTarget}, jobs::monitor_udev_job::EVENT_STORE, process_tools::{self, await_process, Pid, RequestingProcess}, diff --git a/vuinputd/src/jobs/mknod_device_in_container_job.rs b/vuinputd/src/jobs/mknod_device_in_container_job.rs index 90cc424..3159c68 100644 --- a/vuinputd/src/jobs/mknod_device_in_container_job.rs +++ b/vuinputd/src/jobs/mknod_device_in_container_job.rs @@ -14,10 +14,7 @@ use async_io::Timer; use log::debug; use crate::{ - actions::{ - action::Action, - runtime_data::{read_udev_data}, - }, + actions::{action::Action, runtime_data::read_udev_data}, job_engine::job::{Job, JobTarget}, jobs::monitor_udev_job::EVENT_STORE, process_tools::{self, await_process, Pid, RequestingProcess}, @@ -102,16 +99,14 @@ impl Job for MknodDeviceInContainerJob { impl MknodDeviceInContainerJob { async fn inject_in_container(self) { - let mknod_device_action = Action::MknodDevice { path: self.dev_path.clone(), major: self.major, minor: self.minor, }; - let child_pid = - process_tools::start_action(mknod_device_action, &self.requesting_process) - .expect("subprocess should work"); + let child_pid = process_tools::start_action(mknod_device_action, &self.requesting_process) + .expect("subprocess should work"); let _exit_info = await_process(Pid::Pid(child_pid)).await.unwrap(); self.set_state(&State::Finished); diff --git a/vuinputd/src/jobs/mod.rs b/vuinputd/src/jobs/mod.rs index c1bb9e4..242f0ab 100644 --- a/vuinputd/src/jobs/mod.rs +++ b/vuinputd/src/jobs/mod.rs @@ -2,7 +2,7 @@ // // Author: Johannes Leupolz -pub mod mknod_device_in_container_job; pub mod emit_udev_event_in_container_job; +pub mod mknod_device_in_container_job; pub mod monitor_udev_job; pub mod remove_from_container_job; diff --git a/vuinputd/src/jobs/remove_from_container_job.rs b/vuinputd/src/jobs/remove_from_container_job.rs index 1e9cfb0..a02836b 100644 --- a/vuinputd/src/jobs/remove_from_container_job.rs +++ b/vuinputd/src/jobs/remove_from_container_job.rs @@ -11,9 +11,7 @@ use std::{ use log::debug; use crate::{ - actions::{ - action::Action, - }, + actions::action::Action, job_engine::job::{Job, JobTarget}, jobs::monitor_udev_job::EVENT_STORE, process_tools::{self, await_process, Pid, RequestingProcess}, diff --git a/vuinputd/src/process_tools/mod.rs b/vuinputd/src/process_tools/mod.rs index 70e562c..f57e045 100644 --- a/vuinputd/src/process_tools/mod.rs +++ b/vuinputd/src/process_tools/mod.rs @@ -12,7 +12,7 @@ use std::{ unix::process::CommandExt, }, path::Path, - process::{Command}, + process::Command, sync::OnceLock, };