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

Reply via email to