Skip to content

Commit

Permalink
fix(Device Hiding): use new method for hiding devices
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowApex committed Feb 7, 2025
1 parent 2746d28 commit 26637aa
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ log = { version = "0.4.22", features = [
"release_max_level_debug",
] }
mio = { version = "0.8.11", features = ["os-poll", "os-ext", "net"] }
nix = { version = "0.29.0", features = ["fs"] }
nix = { version = "0.29.0", features = ["fs", "ioctl"] }
packed_struct = "0.10.1"
procfs = "0.16.0"
rand = "0.8.5"
Expand Down
43 changes: 38 additions & 5 deletions src/udev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,31 @@ pub mod device_test;

pub mod device;

use std::{error::Error, fs, path::Path};
use std::{error::Error, fs, os::fd::IntoRawFd, path::Path};

use nix::ioctl_write_int;
use tokio::process::Command;
use udev::Enumerator;

use self::device::Device;

const RULE_PRIORITY: &str = "73";
const RULES_PREFIX: &str = "/run/udev/rules.d";

ioctl_write_int!(
/// Revoke access to an evdev device
/// https://github.com/torvalds/linux/blob/v6.13/include/uapi/linux/input.h#L187
/// https://github.com/torvalds/linux/blob/v6.13/drivers/input/evdev.c#L1090-L1094
eviocrevoke, b'E', 0x91
);

ioctl_write_int!(
/// Revoke access to an hidraw device
/// https://github.com/torvalds/linux/blob/v6.13/include/uapi/linux/hidraw.h#L49
/// https://github.com/torvalds/linux/blob/v6.13/drivers/hid/hidraw.c#L447-L454
hidiocrevoke, b'H', 0x0d
);

/// Hide the given input device from regular users.
pub async fn hide_device(path: String) -> Result<(), Box<dyn Error>> {
// Get the device to hide
Expand Down Expand Up @@ -42,19 +58,36 @@ pub async fn hide_device(path: String) -> Result<(), Box<dyn Error>> {
{match_rule}, GOTO="inputplumber_valid"
GOTO="inputplumber_end"
LABEL="inputplumber_valid"
KERNEL=="hidraw[0-9]*|js[0-9]*|event[0-9]*", SUBSYSTEM=="{subsystem}", MODE="000", GROUP="root", TAG-="uaccess", RUN+="{chmod_cmd} 000 {path}"
ACTION=="add", KERNEL=="hidraw[0-9]*|js[0-9]*|event[0-9]*", SUBSYSTEM=="{subsystem}", MODE="000", GROUP="root", SYMLINK+="inputplumber/%k", TAG-="uaccess", RUN:="{chmod_cmd} 000 {path}"
LABEL="inputplumber_end"
"#
);

// Write the udev rule
fs::create_dir_all(RULES_PREFIX)?;
let rule_path = format!("{RULES_PREFIX}/96-inputplumber-hide-{name}.rules");
let rule_path = format!("{RULES_PREFIX}/{RULE_PRIORITY}-inputplumber-hide-{name}.rules");
fs::write(rule_path, rule)?;

// Reload udev
reload_children(parent).await?;

// Break ioctl to the device
let file = std::fs::File::options()
.read(true)
.write(true)
.open(&path)?;
let device = file.into_raw_fd();
log::debug!("Revoking ioctl for '{path}'");
match subsystem.as_str() {
"input" => unsafe {
eviocrevoke(device, 0)?;
},
"hidraw" => unsafe {
hidiocrevoke(device, 0)?;
},
_ => (),
}

Ok(())
}

Expand All @@ -66,7 +99,7 @@ pub async fn unhide_device(path: String) -> Result<(), Box<dyn Error>> {
let Some(parent) = device.get_parent() else {
return Err("Unable to determine parent for device".into());
};
let rule_path = format!("{RULES_PREFIX}/96-inputplumber-hide-{name}.rules");
let rule_path = format!("{RULES_PREFIX}/{RULE_PRIORITY}-inputplumber-hide-{name}.rules");
fs::remove_file(rule_path)?;

// Reload udev
Expand All @@ -83,7 +116,7 @@ pub async fn unhide_all() -> Result<(), Box<dyn Error>> {
continue;
};
let filename = entry.file_name().to_string_lossy().to_string();
if !filename.starts_with("96-inputplumber-hide") {
if !filename.starts_with(format!("{RULE_PRIORITY}-inputplumber-hide").as_str()) {
continue;
}
let path = entry.path().to_string_lossy().to_string();
Expand Down

0 comments on commit 26637aa

Please sign in to comment.