diff --git a/src/modules/module-flatpak.c b/src/modules/module-flatpak.c index 59c6f67a2..3c981201d 100644 --- a/src/modules/module-flatpak.c +++ b/src/modules/module-flatpak.c @@ -139,20 +139,25 @@ static void client_info_free(struct client_info *cinfo) static int check_sandboxed(struct pw_client *client) { char root_path[2048]; - int root_fd, info_fd, res; - const struct ucred *ucred; + int root_fd, info_fd, res, pid; + const char *str; + const struct pw_properties *props; struct stat stat_buf; - ucred = pw_client_get_ucred(client); + if ((props = pw_client_get_properties(client))) + str = pw_properties_get(props, PW_CLIENT_PROP_UCRED_PID); + else + str = NULL; - if (ucred) { - pw_log_info("client has trusted pid %d", ucred->pid); + if (str) { + pid = atoi(str); + pw_log_info("client has trusted pid %d", pid); } else { pw_log_info("no trusted pid found, assuming not sandboxed\n"); return 0; } - sprintf(root_path, "/proc/%u/root", ucred->pid); + sprintf(root_path, "/proc/%u/root", pid); root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); if (root_fd == -1) { /* Not able to open the root dir shouldn't happen. Probably the app died and @@ -182,11 +187,22 @@ static int check_sandboxed(struct pw_client *client) return 1; } +static int get_client_prop(struct pw_client *client, const char *prop) +{ + const struct pw_properties *props; + const char *str; + if ((props = pw_client_get_properties(client)) == NULL) + return -EINVAL; + if ((str = pw_properties_get(props, prop)) == NULL) + return -EINVAL; + return atoi(str); +} + static bool check_global_owner(struct pw_client *client, struct pw_global *global) { struct pw_client *owner; - const struct ucred *owner_ucred, *client_ucred; + int owner_uid, client_uid; if (global == NULL) return false; @@ -195,14 +211,14 @@ check_global_owner(struct pw_client *client, struct pw_global *global) if (owner == NULL) return false; - owner_ucred = pw_client_get_ucred(owner); - client_ucred = pw_client_get_ucred(client); + owner_uid = get_client_prop(owner, PW_CLIENT_PROP_UCRED_UID); + client_uid = get_client_prop(client, PW_CLIENT_PROP_UCRED_UID); - if (owner_ucred == NULL || client_ucred == NULL) + if (owner_uid < 0 || client_uid < 0) return false; /* same user can see eachothers objects */ - return owner_ucred->uid == client_ucred->uid; + return owner_uid == client_uid; } static int @@ -320,7 +336,9 @@ static void do_portal_check(struct client_info *cinfo) device = "camera"; - pid = pw_client_get_ucred(client)->pid; + pid = get_client_prop(client, PW_CLIENT_PROP_UCRED_PID); + if (pid < 0) + goto not_allowed; if (!dbus_message_append_args(m, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_INVALID)) goto message_failed; diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index 4929fc6d7..131657f61 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -313,24 +313,32 @@ static struct pw_client *client_new(struct server *s, int fd) struct pw_protocol *protocol = s->this.protocol; struct protocol_data *pd = protocol->user_data; socklen_t len; - struct ucred ucred, *ucredp; + struct ucred ucred; struct pw_core *core = protocol->core; struct pw_properties *props; - - len = sizeof(ucred); - if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) { - pw_log_error("no peercred: %m"); - ucredp = NULL; - } else { - ucredp = &ucred; - } + char buffer[1024]; props = pw_properties_new(PW_CLIENT_PROP_PROTOCOL, "protocol-native", NULL); if (props == NULL) goto no_props; + len = sizeof(ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) { + pw_log_error("no peercred: %m"); + } else { + pw_properties_setf(props, PW_CLIENT_PROP_UCRED_PID, "%d", ucred.pid); + pw_properties_setf(props, PW_CLIENT_PROP_UCRED_UID, "%d", ucred.uid); + pw_properties_setf(props, PW_CLIENT_PROP_UCRED_GID, "%d", ucred.gid); + } + + len = sizeof(buffer); + if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buffer, &len) < 0) { + pw_log_error("no peersec: %m"); + } else { + pw_properties_setf(props, PW_CLIENT_PROP_SEC_LABEL, "%s", buffer); + } + client = pw_client_new(protocol->core, - ucredp, props, sizeof(struct client_data)); if (client == NULL) diff --git a/src/pipewire/client.c b/src/pipewire/client.c index 8259db2a7..a09e3da84 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -150,7 +150,6 @@ static const struct pw_core_events core_events = { */ SPA_EXPORT struct pw_client *pw_client_new(struct pw_core *core, - struct ucred *ucred, struct pw_properties *properties, size_t user_data_size) { @@ -165,20 +164,12 @@ struct pw_client *pw_client_new(struct pw_core *core, pw_log_debug("client %p: new", this); this->core = core; - if ((this->ucred_valid = (ucred != NULL))) - this->ucred = *ucred; if (properties == NULL) properties = pw_properties_new(NULL, NULL); if (properties == NULL) return NULL; - if (ucred) { - pw_properties_setf(properties, PW_CLIENT_PROP_UCRED_PID, "%d", ucred->pid); - pw_properties_setf(properties, PW_CLIENT_PROP_UCRED_UID, "%d", ucred->uid); - pw_properties_setf(properties, PW_CLIENT_PROP_UCRED_GID, "%d", ucred->gid); - } - pw_array_init(&impl->permissions, 1024); this->properties = properties; @@ -273,15 +264,6 @@ const struct pw_properties *pw_client_get_properties(struct pw_client *client) return client->properties; } -SPA_EXPORT -const struct ucred *pw_client_get_ucred(struct pw_client *client) -{ - if (!client->ucred_valid) - return NULL; - - return &client->ucred; -} - SPA_EXPORT void *pw_client_get_user_data(struct pw_client *client) { diff --git a/src/pipewire/client.h b/src/pipewire/client.h index f653f93eb..a454d4a2f 100644 --- a/src/pipewire/client.h +++ b/src/pipewire/client.h @@ -24,12 +24,6 @@ extern "C" { #endif -#ifndef __USE_GNU -#define __USE_GNU -#endif - -#include - #include /** \class pw_client @@ -119,11 +113,11 @@ struct pw_client_events { #define PW_CLIENT_PROP_UCRED_PID "pipewire.ucred.pid" /**< Client pid, set by protocol */ #define PW_CLIENT_PROP_UCRED_UID "pipewire.ucred.uid" /**< Client uid, set by protocol*/ #define PW_CLIENT_PROP_UCRED_GID "pipewire.ucred.gid" /**< client gid, set by protocol*/ +#define PW_CLIENT_PROP_SEC_LABEL "pipewire.sec.label" /**< client security label, set by protocol*/ /** Create a new client. This is mainly used by protocols. */ struct pw_client * pw_client_new(struct pw_core *core, /**< the core object */ - struct ucred *ucred, /**< optional ucred */ struct pw_properties *properties, /**< client properties */ size_t user_data_size /**< extra user data size */); @@ -163,9 +157,6 @@ struct pw_resource *pw_client_find_resource(struct pw_client *client, uint32_t i /** Get the global associated with this client */ struct pw_global *pw_client_get_global(struct pw_client *client); -/** Get the ucred from a client or NULL when not specified/valid */ -const struct ucred *pw_client_get_ucred(struct pw_client *client); - /** listen to events from this client */ void pw_client_add_listener(struct pw_client *client, struct spa_hook *listener, diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 42612f1da..9e51d21a9 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -99,8 +99,6 @@ struct pw_client { struct pw_properties *properties; /**< Client properties */ struct pw_client_info info; /**< client info */ - bool ucred_valid; /**< if the ucred member is valid */ - struct ucred ucred; /**< ucred information */ struct pw_resource *core_resource; /**< core resource object */