On Fri, 2021-02-05 at 10:57 +0100, Ludovic Courtès wrote: > Hi Maxime, > > > I don't know how I should implement this properly in Guile, though. > > In C, I would use loop using openat with O_NOFOLLOW, in combination > > with stat, but Guile doesn't have openat or O_NOFOLLOW. > > In this case we need a solution without openat for now. Perhaps simply > changing ‘mkdir-p/perms’ to ‘lstat’ components as it goes? A compromised service could create a component as a regular file or directory, and quickly replace it with a symlink after the activation gexp checks the component wasn't a symlink but before the chown or chmod. It's a tiny window though. I was going to say this tiny ‘exploitation window’ could be ignored for now until an API to openat & other *at C functions makes it into guile, but then I checked the inotify(7) API. Apparently, inotify events are generated for directory accesses. > > [...] > > I'll look into writing a concrete proposal for *at in guile. > > I'll post a link to the guile mailing list message when it has > > been composed and sent. Link: https://lists.gnu.org/archive/html/bug-guile/2021-02/msg00002.html > The difficulty in designing such an interface is that the Scheme API is > more about ports than it’s about file names and file descriptors. This doesn't seem a large issue to me. Ports for directories can be made with 'open': (open "/home" O_RDONLY). Example use of for changing permission bits of "/home/USER" with proposed API: (let* ((directory (open "/home" O_RDONLY)) ;; in the C API, this translates to: ;; openat(directory-fd, "USER", O_IDK) ;; (replace O_IDK with appropriate open flags) (file-in-dir (open (make-path-at directory "USER") O_IDK))) (chmod file-in-dir #o077) (chown file-in-dir 0 0)) I'll try to implement this API in Scheme (using the FFI), and post it at https://notabug.org/mdevos/things. I'll post a follow-up messsage once I've implemented the basics (openat, chmodat, chownat). Greetings, Maxime.