Re: [RFC] connectat()/bindat() or an alternative design
From: Cong Wang <hidden>
Date: 2026-07-02 00:32:50
Also in:
linux-fsdevel
On Tue, Jun 30, 2026 at 04:22:25PM -0400, John Ericson wrote:
I'm bumping this and adding new recipients again in light of the discussion happening elsewhere in <https://lore.kernel.org/all/a49ce818-f38d-41b0-bbf7-80b8aad998b1@app.fastmail.com/ (local)>. I don't want to count my chickens before they are hatched, but it is looking to me like a consensus in that thread is building around the ability to opt into intentionally empty/unusable root and working directories (at least with nullfs, maybe but less likely with other mechanisms instead). That new functionality concretizes the motivation for what I am proposing in this thread: in such a world, there is little to no point binding listening sockets in the file system, because the containing directory would have to be conveyed by file descriptor anyways --- might as well just directly convey the socket to connect to by file descriptor. Likewise, abstract sockets are not appealing, because the abstract socket namespace is either too coarse-grained (leaking info in the same way root/cwd would), or too cumbersome to keep it from leaking. To recap (with some slight changes, like renames), my latest proposal (a new version, not either of the two variations in the original email) is new syscalls `bind_unix_anon` and `connectat`, supporting a workflow like this: /* server */ int lfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); int addrfd = bind_unix_anon( lfd, /*flags, for the future*/0); listen(lfd, 64); /* client, handed `addrfd` */ int cfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); connectat(addrfd, cfd, AT_EMPTY_PATH); Or, more radically, `bind_unix_anon` and `connectat` could let one skip the initial `socket` calls by returning those new sockets directly:
Hm? Why not just setsockopt()? Something like:
struct unix_lookup_ctx {
int dirfd;
__u64 resolve_flags; /* RESOLVE_BENEATH, RESOLVE_NO_SYMLINKS, etc. */
__u64 op_flags; /* maybe future */
};
setsockopt(fd, SOL_UNIX, UNIX_NEXT_LOOKUP,
&ctx, sizeof(ctx));
bind(fd, (struct sockaddr *)&addr, addrlen);
/* or connect(fd, ...) */
Zero new syscall is needed.
Regards,
Cong