Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Essentially what you really want is the sudo command to acquire a temporary capability token to edit that specific file.

This should be doable with an XDG portal model, right?



It's doable by opening the file in a privileged process (sudo) and passing the file descriptor to a non-privileged process.

Maybe one could make a sudoedit that opens a file in sudo process and then spawns a non-privileged editor process which inherits the file descriptor and is given the /dev/fd/ path on the command line, so it stays none the wiser about the whole process.


Sounds like a bit of recipe for accidentally handing access to an unintended privileged fd through inheritance (ignoring the /dev/fd one) such that a compromised unprivileged SUDO_EDITOR value gives you sudo access. Maybe not likely, but I’d really be hesitant about any feature that relies on implicit fd inheritance…


Another option could be to open a UNIX socket in the privileged sudo process, spawn an unprivileged child process 'shim' that connects to that socket, and then the sudo process can pass the file descriptor over the socket. Since the child shim is 'clean', it should have nothing more than stdin/out/err open, plus now this passed FD. Then the shim can spawn the target program and allow it to inherit just the passed FD.

I think the larger issue is that I doubt many (if any?) editors allow opening a file via an inherited file descriptor! I guess some will read stdin (the shim could close stdin and then dup2() it into its place), but then there's no way to save the file back when finished.


Close all other fds between fork and exec then (you can look at the code of base::LaunchProcess in Chromium for an example). It’s a minuscule amount of code to audit compared to XDG portals. And it’s backwards-compatible with decades of unix programs.

For a more complicated solution: spawn a zygote process early with a unix socket which you’ll use to send the fd later. Zygote at start drops provileges. When it receives the fd, it closes the socket and execs the editor.


I’m not saying it’s not possible to do correctly. But do you not agree that the first is hard to correctly (can overlook an fd) while the latter is a lot of complexity?

There is the CLOEXEC flag which is the intended way to manage this but it’s not the default and you have to be diligent about setting it which again carries its own set of challenges.

What you’d really want is CLOEXEC implicitly on all fds and having to explicitly opt in for fd inheritance.


Rust stdlib opens all fds with CLOEXEC set. You have to explicitly disable it when you want the child to inhert the fd.


That would be ideal, but we'd need a new syscall for that.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: