Why was udisks2 openDevice prefered over std::fs::File::Open

In https://github.com/pop-os/popsicle/blob/master/gtk/src/flash.rs#L172, I notice that in order to write to a block device (like /dev/sdX), the authors use the udisks2's openDevice method:

fn udisks_open(block_device: &Path) -> anyhow::Result<File> {
    let connection = Connection::new_system()?;

    let mut dbus_path = b"/org/freedesktop/UDisks2/block_devices/".to_vec();
    dbus_path.extend_from_slice(block_device.strip_prefix("/dev")?.as_os_str().as_bytes());
    let dbus_path = ::dbus::strings::Path::new(dbus_path).map_err(anyhow::Error::msg)?;

    let proxy = Proxy::new(
        "org.freedesktop.UDisks2",
        &dbus_path,
        Duration::new(25, 0),
        &connection,
    );

    let mut options = UDisksOptions::new();
    options.insert("flags", Variant(Box::new(libc::O_SYNC)));
    let res: (OwnedFd,) = proxy.method_call(
        "org.freedesktop.UDisks2.Block",
        "OpenDevice",
        ("rw", options),
    )?;

    Ok(unsafe { File::from_raw_fd(res.0.into_fd()) })
}

I am trying to figure out why is this preferable to std::fs::File::open or something similar as:

let mut output = fs::OpenOptions::new()
                .write(true)
                .create(true)
                .custom_flags(libc::O_SYNC)
                .open(output_drive.parent.device)
                .expect("Could not open output file/device");

Is this related to file permissions?


I didn't ask this on Github because I don't have an account there.

1 Like

i'm not qualified to confidently answer your question, but here's what udisks2 seems to be doing under the hood:

(it's an open syscall and some error handling)

Block devices are usually restricted to root access, but I think udisks will open it on your behalf, after appropriate permission checks, so you can access "user" devices like a thumb drive.

1 Like

That is the exact reason it switched to udisks2 from directly opening /dev/...: https://github.com/pop-os/popsicle/commit/6d9129437208fb293a132ca8e3e5a0b41d4d1a87#diff-3ef85dbdce155de83201e640a03303f8R144

feat: Run without root using UDisks2, for security and flatpak

The "privileged" thread is now removed. As is the popsicle-pkexec
script.

This also ports the code to using the Task struct defined by the
library.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.