On Do, 22.08.24 17:06, Florian Weimer (fwei...@redhat.com) wrote: > > You don't really have to live with such a limitation. In systemd we > > have code that works around this limitation via O_PATH. i.e. when > > connect()ing you first open the socket inode with O_PATH, and then you > > fire the connect() specifying /proc/self/fd/<fd> as path. That always > > fits into the 108ch limit. > > Do you think this is useful more generally? What about opening files > with names longer than PATH_MAX?
Internally in systemd, we have a function chase() which basically does something like canonicalize_file_name(), but built around O_PATH, and ultimately returning an O_PATH fd. It resolves paths in userspace, taking alternative roots into account, being careful with symlinks and so on. As a side effect this means we do not have any limits on paths lengths anywhere. I mean, things like this I sense are really fundamental if you want to safely use the POSIX file system API, without risking being tricked into opening/creating files one shouldn't use by the various tricks available. But I have no illusions there: I think it's really tough to wrap this into a public libc-level API. > > bind()ing to an overly long unix socket path is also doable, but > > harder (since you cannot O_PATH on an inode that doesn't exist > > yet). The way I'd do it is via chdir() to the dir of the target path > > and binding to a relative path then. But chdir() is of course icky, > > since it's a global property of a process, hence will affect all > > threads. Hence, maybe do this in a short-lived forked off process. > > I would have expected that it's possible to use a directory descriptor > under /proc/self/fd as the base, but that doesn't seem to work for some > reason. Well, the path gets propagated into what /proc/net/unix shows, hence I don't think going via /proc/self/fd/ is desriable there. I think the best option is to use a relative bind then, via chdir() as I mentioned. It will then just show a relative path, which is not perfect, but at least communicates clearly what's going on, and still is descriptive. From my perspective I think having the ability to connect to sockets with arbitrarily long paths is a lot more interesting then the ability to bind to them. That's because connection paths often are result of concatenating paths due to nesting of chroot/container trees, bind mounting and such. But services typically bind their own sockets as somewhat constant singletons, without having to nest anything. Or in other words: if you provide an API via AF_UNIX, already for compat with other tools it's a really good idea to stick to a 109ch path. But if you connect to someone's API via AF_UNIX, you never know what you'll get passed because of bind mounts/nesting yadda yadda, it's great to be able to consume anything they throw at you then. It's an instance of the rule to be lenient in what you accept, and strict with what you generate i guess. Hence, in systemd's tree, we do the O_PATH thing only for connect(), we do not actually bother with any of that for the binding of sockets. Lennart -- Lennart Poettering, Berlin -- _______________________________________________ devel mailing list -- devel@lists.fedoraproject.org To unsubscribe send an email to devel-le...@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue