tree-wide: symlink well-known Varlink service entry point sockets into /run/varlink/registry/ (#40590)

This is generally useful, but is particularly useful in context of
https://github.com/mvo5/varlink-proxy-rs which can expose a set of local
Varlink services via a HTTP bridge. The idea is that the sockets linked
into /run/varlink/registry/ are candidates for being exposed like that.

/cc @mvo5
This commit is contained in:
Lennart Poettering
2026-02-09 11:54:15 +01:00
committed by GitHub
37 changed files with 290 additions and 18 deletions
+18 -6
View File
@@ -26,7 +26,10 @@
CHASE_STEP | \
CHASE_PROHIBIT_SYMLINKS | \
CHASE_PARENT | \
CHASE_MKDIR_0755)
CHASE_MKDIR_0755 | \
CHASE_MUST_BE_DIRECTORY | \
CHASE_MUST_BE_REGULAR | \
CHASE_MUST_BE_SOCKET)
bool unsafe_transition(const struct stat *a, const struct stat *b) {
/* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
@@ -133,7 +136,6 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
int r;
assert(!FLAGS_SET(flags, CHASE_PREFIX_ROOT));
assert(!FLAGS_SET(flags, CHASE_MUST_BE_DIRECTORY|CHASE_MUST_BE_REGULAR));
assert(!FLAGS_SET(flags, CHASE_STEP|CHASE_EXTRACT_FILENAME));
assert(!FLAGS_SET(flags, CHASE_NO_AUTOFS|CHASE_TRIGGER_AUTOFS));
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
@@ -328,6 +330,10 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
if (FLAGS_SET(flags, CHASE_PARENT))
flags |= CHASE_MUST_BE_DIRECTORY;
/* If multiple flags are set now, fail immediately */
if (FLAGS_SET(flags, CHASE_MUST_BE_DIRECTORY) + FLAGS_SET(flags, CHASE_MUST_BE_REGULAR) + FLAGS_SET(flags, CHASE_MUST_BE_SOCKET) > 1)
return -EBADSLT;
for (todo = buffer;;) {
_cleanup_free_ char *first = NULL;
_cleanup_close_ int child = -EBADF;
@@ -566,6 +572,12 @@ success:
if (r < 0)
return r;
}
if (FLAGS_SET(flags, CHASE_MUST_BE_SOCKET)) {
r = stat_verify_socket(&st);
if (r < 0)
return r;
}
}
if (ret_path) {
@@ -872,7 +884,7 @@ int chase_and_opendir(const char *path, const char *root, ChaseFlags chase_flags
DIR *d;
int r;
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR|CHASE_MUST_BE_SOCKET)));
assert(ret_dir);
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
@@ -970,7 +982,7 @@ int chase_and_fopen_unlocked(
int mode_flags, r;
assert(path);
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_DIRECTORY)));
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_DIRECTORY|CHASE_MUST_BE_SOCKET)));
assert(open_flags);
assert(ret_file);
@@ -1040,7 +1052,7 @@ int chase_and_openat(
_cleanup_free_ char *p = NULL, *fname = NULL;
int r;
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_SOCKET)));
XOpenFlags xopen_flags = 0;
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_DIRECTORY))
@@ -1086,7 +1098,7 @@ int chase_and_opendirat(int dir_fd, const char *path, ChaseFlags chase_flags, ch
DIR *d;
int r;
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR|CHASE_MUST_BE_SOCKET)));
assert(ret_dir);
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
+1
View File
@@ -29,6 +29,7 @@ typedef enum ChaseFlags {
CHASE_EXTRACT_FILENAME = 1 << 13, /* Only return the last component of the resolved path */
CHASE_MUST_BE_DIRECTORY = 1 << 14, /* Fail if returned inode fd is not a dir */
CHASE_MUST_BE_REGULAR = 1 << 15, /* Fail if returned inode fd is not a regular file */
CHASE_MUST_BE_SOCKET = 1 << 16, /* Fail if returned inode fd is not a socket */
} ChaseFlags;
bool unsafe_transition(const struct stat *a, const struct stat *b);
+15
View File
@@ -142,6 +142,21 @@ int is_symlink(const char *path) {
return verify_stat_at(AT_FDCWD, path, false, stat_verify_symlink, false);
}
int stat_verify_socket(const struct stat *st) {
assert(st);
if (S_ISLNK(st->st_mode))
return -ELOOP;
if (S_ISDIR(st->st_mode))
return -EISDIR;
if (!S_ISSOCK(st->st_mode))
return -ENOTSOCK;
return 0;
}
int stat_verify_linked(const struct stat *st) {
assert(st);
+2
View File
@@ -20,6 +20,8 @@ int stat_verify_symlink(const struct stat *st);
int fd_verify_symlink(int fd);
int is_symlink(const char *path);
int stat_verify_socket(const struct stat *st);
int stat_verify_linked(const struct stat *st);
int fd_verify_linked(int fd);