Prompted by https://github.com/systemd/systemd/pull/36858#discussion_r2017719305
and #36833
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
+#include "random-util.h"
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"
return setsockopt_int(fd, SOL_SOCKET, SO_BINDTOIFINDEX, ifindex);
}
+int socket_autobind(int fd, char **ret_name) {
+ _cleanup_free_ char *name = NULL;
+ uint64_t random;
+ int r;
+
+ /* Generate a random abstract socket name and bind fd to it. This is modeled after the kernel
+ * "autobind" feature, but uses 64-bit random number internally. */
+
+ assert(fd >= 0);
+ assert(ret_name);
+
+ random = random_u64();
+
+ if (asprintf(&name, "@%" PRIu64, random) < 0)
+ return -ENOMEM;
+
+ union sockaddr_union sa;
+ assert_cc(DECIMAL_STR_MAX(uint64_t) < sizeof(sa.un.sun_path));
+
+ r = sockaddr_un_set_path(&sa.un, name);
+ if (r < 0)
+ return r;
+
+ if (bind(fd, &sa.sa, r) < 0)
+ return -errno;
+
+ *ret_name = TAKE_PTR(name);
+ return 0;
+}
+
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) {
ssize_t n;
int socket_bind_to_ifname(int fd, const char *ifname);
int socket_bind_to_ifindex(int fd, int ifindex);
+int socket_autobind(int fd, char **ret_name);
+
/* Define a 64-bit version of timeval/timespec in any case, even on 32-bit userspace. */
struct timeval_large {
uint64_t tvl_sec, tvl_usec;
if (r < 0)
log_debug_errno(r, "Failed to enable SO_PASSPIDFD, ignoring: %m");
- /* Pick an address via auto-bind */
- union sockaddr_union sa = {
- .sa.sa_family = AF_UNIX,
- };
- if (bind(socket_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path)) < 0)
- return log_error_errno(errno, "Failed to bind AF_UNIX socket: %m");
-
_cleanup_free_ char *addr_string = NULL;
- r = getsockname_pretty(socket_fd, &addr_string);
+ r = socket_autobind(socket_fd, &addr_string);
if (r < 0)
- return log_error_errno(r, "Failed to get socket name: %m");
+ return log_error_errno(r, "Failed to bind notify socket: %m");
_cleanup_free_ char *c = strv_join(command, " ");
if (!c)