From bed325a7ffa4476bf2907fad8e73aeb5900357c1 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Sat, 6 Sep 2025 10:44:13 +0200 Subject: [PATCH] add permissions to actions --- include/action.h | 1 + include/common/spawn.h | 2 +- src/action.c | 12 +++++++++++- src/common/spawn.c | 12 +++++++++++- src/config/session.c | 6 +++--- src/main.c | 2 +- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/action.h b/include/action.h index b09aa35c..c767b445 100644 --- a/include/action.h +++ b/include/action.h @@ -18,6 +18,7 @@ struct action { */ uint32_t type; /* enum action_type */ + uint32_t allowed_interfaces; struct wl_list args; /* struct action_arg.link */ }; diff --git a/include/common/spawn.h b/include/common/spawn.h index 3f766eff..9145c727 100644 --- a/include/common/spawn.h +++ b/include/common/spawn.h @@ -21,7 +21,7 @@ pid_t spawn_primary_client(const char *command); * spawn_async_no_shell - execute asynchronously * @command: command to be executed */ -void spawn_async_no_shell(char const *command); +void spawn_async_no_shell(char const *command, int socket_fd); /** * spawn_piped - execute asynchronously diff --git a/src/action.c b/src/action.c index 2cfa6be6..35537b8b 100644 --- a/src/action.c +++ b/src/action.c @@ -27,6 +27,7 @@ #include "menu/menu.h" #include "output.h" #include "output-virtual.h" +#include "permissions.h" #include "regions.h" #include "ssd.h" #include "theme.h" @@ -302,6 +303,9 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char if (!strcmp(argument, "command") || !strcmp(argument, "execute")) { action_arg_add_str(action, "command", content); goto cleanup; + } else if (!strcmp(argument, "allow")) { + action->allowed_interfaces |= parse_privileged_interface(content); + goto cleanup; } break; case ACTION_TYPE_MOVE_TO_EDGE: @@ -570,6 +574,7 @@ action_create(const char *action_name) struct action *action = znew(*action); action->type = action_type; + action->allowed_interfaces = 0; wl_list_init(&action->args); return action; } @@ -1077,7 +1082,12 @@ run_action(struct view *view, struct action *action, struct buf cmd = BUF_INIT; buf_add(&cmd, action_get_str(action, "command", NULL)); buf_expand_tilde(&cmd); - spawn_async_no_shell(cmd.data); + int socket_fd = -1; + if (action->allowed_interfaces) { + socket_fd = permissions_context_create( + server.wl_display, action->allowed_interfaces); + } + spawn_async_no_shell(cmd.data, socket_fd); buf_reset(&cmd); break; } diff --git a/src/common/spawn.c b/src/common/spawn.c index 9468b2b9..1cb4dadd 100644 --- a/src/common/spawn.c +++ b/src/common/spawn.c @@ -43,10 +43,11 @@ set_cloexec(int fd) } void -spawn_async_no_shell(char const *command) +spawn_async_no_shell(char const *command, int socket_fd) { GError *err = NULL; gchar **argv = NULL; + char socket_str[32]; assert(command); @@ -73,6 +74,12 @@ spawn_async_no_shell(char const *command) reset_signals_and_limits(); setsid(); + if (socket_fd != -1) { + snprintf(socket_str, sizeof(socket_str), "%d", socket_fd); + if (setenv("WAYLAND_SOCKET", socket_str, 1) != 0) { + wlr_log(WLR_ERROR, "unable to setenv() WAYLAND_SOCKET"); + } + } grandchild = fork(); if (grandchild == 0) { execvp(argv[0], argv); @@ -84,6 +91,9 @@ spawn_async_no_shell(char const *command) default: break; } + if (socket_fd != -1) { + close(socket_fd); + } waitpid(child, NULL, 0); out: g_strfreev(argv); diff --git a/src/config/session.c b/src/config/session.c index 7df6236c..cf1b69c0 100644 --- a/src/config/session.c +++ b/src/config/session.c @@ -219,12 +219,12 @@ execute_update(const char *env_keys, const char *env_unset_keys, bool initialize char *cmd = strdup_printf("dbus-update-activation-environment %s", initialize ? env_keys : env_unset_keys); - spawn_async_no_shell(cmd); + spawn_async_no_shell(cmd, -1); free(cmd); cmd = strdup_printf("systemctl --user %s %s", initialize ? "import-environment" : "unset-environment", env_keys); - spawn_async_no_shell(cmd); + spawn_async_no_shell(cmd, -1); free(cmd); } @@ -320,7 +320,7 @@ session_run_script(const char *script) } wlr_log(WLR_INFO, "run session script %s", path->string); char *cmd = strdup_printf("sh %s", path->string); - spawn_async_no_shell(cmd); + spawn_async_no_shell(cmd, -1); free(cmd); if (!should_merge_config) { diff --git a/src/main.c b/src/main.c index 373f4480..83fee58f 100644 --- a/src/main.c +++ b/src/main.c @@ -153,7 +153,7 @@ idle_callback(void *data) session_autostart_init(); if (ctx->startup_cmd) { - spawn_async_no_shell(ctx->startup_cmd); + spawn_async_no_shell(ctx->startup_cmd, -1); } }