dbus: gate the bus socket like INIT_SOCKET

The D-Bus socket was bound world read/write, on the reasoning that
SO_PEERCRED authorizes each method anyway.  That leaves the read-only
surface open to every local user, and it quietly ignores --with-group:
a system that restricts initctl to the wheel group still handed the
same service state to anyone who asked over the bus.

Bind it 0660 and chown it to the configured group, the same gate the
fallback socket has always had.  libink takes the mode as an argument
rather than assuming one, since who may connect is the embedder's
policy, not the library's.

The mode is applied at bind(), so there is no window where the socket
is more permissive than intended.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2026-08-13 10:14:48 +02:00
1 parent c71ccce742
commit d710a23513
6 files changed
+33 -10

No files matched your search

+5 -1
View File
@@ -90,7 +90,11 @@ typedef struct {
/* ---------- server / connection lifecycle ---------- */
int link_server_new (link_server_t **server, const char *path);
/* Bind a listening socket at `path` with file mode `mode`, e.g. 0660
* to keep it to root and one group. The mode is applied at bind(),
* so the socket is never briefly more permissive than asked; setting
* the owning group afterwards is the caller's job. */
int link_server_new (link_server_t **server, const char *path, mode_t mode);
void link_server_free (link_server_t *server);
int link_server_get_fd(const link_server_t *server);
+5 -4
View File
@@ -22,7 +22,7 @@ static void close_save_errno(int fd)
errno = saved;
}
int link_server_new(link_server_t **out, const char *path)
int link_server_new(link_server_t **out, const char *path, mode_t mode)
{
struct sockaddr_un sun = { .sun_family = AF_UNIX };
link_server_t *srv;
@@ -55,12 +55,13 @@ int link_server_new(link_server_t **out, const char *path)
/* fchmod() on a Unix-domain socket fd is a silent no-op on Linux:
* the file mode is fixed at bind() time as (0777 & ~umask). Set
* umask around the bind() so the socket appears with mode 0666
* atomically, no race window. World-accessible by design;
* umask around the bind() so the socket appears with the mode the
* caller asked for atomically, with no window where it is more
* permissive. Who may connect is the caller's policy to set;
* per-method authorization happens later in dispatch via
* SO_PEERCRED. */
{
mode_t oldmask = umask(0111);
mode_t oldmask = umask(0777 & ~mode);
int rc = bind(fd, (struct sockaddr *)&sun, sizeof(sun));
int saved = errno;