This makes it for example possible to move the socket into a directory
that seatd can write to when seatd is not run as root.
---
man/seatd.1.scd | 5 +++--
seatd-launch/seatd-launch.c | 2 +-
seatd/seatd.c | 21 +++++++++++++--------
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/man/seatd.1.scd b/man/seatd.1.scd
index 92f8e4b..4663153 100644
--- a/man/seatd.1.scd
+++ b/man/seatd.1.scd
@@ -28,6 +28,9 @@ seatd - A seat management daemon
Log-level to use. Must be one of debug, info, error or silent. Defaults
to error.
+*-s <socket>*
+ Overwrite the path for the seatd socket.
+
*-v*
Show the version number and quit.
@@ -39,8 +42,6 @@ such as displays and input devices in a multi-session, multi-seat environment.
seatd operates over a UNIX domain socket, with *libseat* providing the
client-side of the protocol.
-The location of the socket for seatd is set at compile-time.
-
# ENVIRONMENT
*SEATD_VTBOUND*
diff --git a/seatd-launch/seatd-launch.c b/seatd-launch/seatd-launch.c
index 65d4f33..be7c7ac 100644
--- a/seatd-launch/seatd-launch.c
+++ b/seatd-launch/seatd-launch.c
@@ -64,7 +64,7 @@ int main(int argc, char *argv[]) {
snprintf(pipebuf, sizeof pipebuf, "%d", readiness_pipe[1]);
char *env[1] = {NULL};
- char *command[] = {"seatd", "-n", pipebuf, "-l", loglevel, "-z", NULL};
+ char *command[] = {"seatd", "-n", pipebuf, "-l", loglevel, "-s", SEATD_DEFAULTPATH, "-z", NULL};
execve(SEATD_INSTALLPATH, command, env);
perror("Could not start seatd");
_exit(1);
diff --git a/seatd/seatd.c b/seatd/seatd.c
index f88e6c9..63c742a 100644
--- a/seatd/seatd.c
+++ b/seatd/seatd.c
@@ -64,6 +64,7 @@ int main(int argc, char *argv[]) {
" -u <user> User to own the seatd socket\n"
" -g <group> Group to own the seatd socket\n"
" -l <loglevel> Log-level, one of debug, info, error or silent\n"
+ " -s <socket> Change the path for the socket (defaults to "SEATD_DEFAULTPATH")\n"
" -v Show the version number\n"
"\n";
@@ -73,7 +74,8 @@ int main(int argc, char *argv[]) {
bool unlink_existing_socket = true;
bool chown_socket = true;
enum libseat_log_level level = LIBSEAT_LOG_LEVEL_INFO;
- while ((c = getopt(argc, argv, "vhn:g:u:l:z")) != -1) {
+ char *socket = SEATD_DEFAULTPATH;
+ while ((c = getopt(argc, argv, "vhn:g:u:l:s:z")) != -1) {
switch (c) {
case 'n':
readiness = atoi(optarg);
@@ -124,6 +126,9 @@ int main(int argc, char *argv[]) {
return 1;
}
break;
+ case 's':
+ socket = optarg;
+ break;
case 'z':
// Running under seatd-launch. We do not unlink files
// to protect against multiple instances, and
@@ -153,19 +158,19 @@ int main(int argc, char *argv[]) {
libseat_set_log_level(level);
struct stat st;
- if (lstat(SEATD_DEFAULTPATH, &st) == 0) {
+ if (lstat(socket, &st) == 0) {
if (!S_ISSOCK(st.st_mode)) {
log_errorf("Non-socket file found at socket path %s, refusing to start",
- SEATD_DEFAULTPATH);
+ socket);
return 1;
} else if (!unlink_existing_socket) {
log_errorf("Socket file found at socket path %s, refusing to start",
- SEATD_DEFAULTPATH);
+ socket);
return 1;
} else {
// We only do this if the socket path is not user specified
- log_infof("Removing leftover socket at %s", SEATD_DEFAULTPATH);
- if (unlink(SEATD_DEFAULTPATH) == -1) {
+ log_infof("Removing leftover socket at %s", socket);
+ if (unlink(socket) == -1) {
log_errorf("Could not remove leftover socket: %s", strerror(errno));
return 1;
}
@@ -179,7 +184,7 @@ int main(int argc, char *argv[]) {
}
int ret = 1;
- int socket_fd = open_socket(SEATD_DEFAULTPATH, uid, gid);
+ int socket_fd = open_socket(socket, uid, gid);
if (socket_fd == -1) {
log_error("Could not create server socket");
goto error_server;
@@ -210,7 +215,7 @@ int main(int argc, char *argv[]) {
ret = 0;
error_socket:
- if (unlink(SEATD_DEFAULTPATH) == -1) {
+ if (unlink(socket) == -1) {
log_errorf("Could not remove socket: %s", strerror(errno));
}
error_server:
--
2.46.2
> Where do people actually set seatd to to suid-root?! That sounds dangerous
> even without this patch.
That's what seatd-launch, which you included changes to in your patch,
is for. When set up, it allows a user to start a compositor through
`seatd-launch` without themselves being root or having seatd runing in
advance, with seatd-launch forking a seatd instance instead. It is
intended for a rather niche use-case previously filled by wlroots'
"builtin" session backend.
The seatd path is not runtime-configurable to ensure that running more
than one instance of seatd will always fail, regardless of whether it is
started as a service or through seatd-launch. This ensures that a second
process cannot be used to eavesdrop on input devices that the first
instance and its users have not approved. You can already change the
path at compile-time if your system requires it.
seatd is not really directly runnable as a user. Users are not supposed
to have direct access to the necessary device files for security
reasons, and some of the ioctl's seatd uses require CAP_SYS_ADMIN.
Instead, seatd is supposed to run as root and hand out the access to
less-privileged users.
Best regards,
Kenny Levinsen