diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-05-10 13:12:22 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-05-10 13:28:18 +0200 |
commit | a2bf4ce96ef8a993dcd867d0eac75c35bba57b3f (patch) | |
tree | f62728e89dcaae916d3b66145d3e0b3d124d3bae | |
parent | 4e70cddf1d87f7f3ac5e8285d87d493e696f39eb (diff) |
protocol: add security label to a client
Don't pass the ucred to the client construct, just set the properties
in the protocol.
Use the client properties to get ucred.
Add the security label to the client properties (from SO_PEERSEC)
-rw-r--r-- | src/modules/module-access.c | 30 | ||||
-rw-r--r-- | src/modules/module-protocol-native.c | 22 | ||||
-rw-r--r-- | src/modules/module-protocol-native/test-connection.c | 2 | ||||
-rw-r--r-- | src/pipewire/client.c | 18 | ||||
-rw-r--r-- | src/pipewire/client.h | 13 |
5 files changed, 35 insertions, 50 deletions
diff --git a/src/modules/module-access.c b/src/modules/module-access.c index 5693b9b0..133f64fb 100644 --- a/src/modules/module-access.c +++ b/src/modules/module-access.c @@ -48,12 +48,12 @@ struct impl { struct spa_hook module_listener; }; -static int check_cmdline(struct pw_client *client, const struct ucred *ucred, const char *str) +static int check_cmdline(struct pw_client *client, int pid, const char *str) { char path[2048]; int fd; - sprintf(path, "/proc/%u/cmdline", ucred->pid); + sprintf(path, "/proc/%u/cmdline", pid); fd = open(path, O_RDONLY); if (fd < 0) @@ -73,13 +73,13 @@ static int check_cmdline(struct pw_client *client, const struct ucred *ucred, co return 0; } -static int check_flatpak(struct pw_client *client, const struct ucred *ucred) +static int check_flatpak(struct pw_client *client, int pid) { char root_path[2048]; int root_fd, info_fd, res; struct stat stat_buf; - 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 @@ -113,23 +113,27 @@ static void core_check_access(void *data, struct pw_client *client) { struct impl *impl = data; - const struct ucred *ucred; struct pw_permission permissions[1]; struct spa_dict_item items[2]; + const struct pw_properties *props; const char *str; - int res; + int pid, res; - ucred = pw_client_get_ucred(client); - if (!ucred) { + pid = -EINVAL; + if ((props = pw_client_get_properties(client)) != NULL) { + if ((str = pw_properties_get(props, PW_CLIENT_PROP_UCRED_PID)) != NULL) + pid = atoi(str); + } + + if (pid < 0) { pw_log_info("no trusted pid found, assuming not sandboxed\n"); goto granted; } else { - pw_log_info("client has trusted pid %d", ucred->pid); + pw_log_info("client has trusted pid %d", pid); } - if (impl->properties && (str = pw_properties_get(impl->properties, "blacklisted")) != NULL) { - res = check_cmdline(client, ucred, str); + res = check_cmdline(client, pid, str); if (res == 0) goto granted; if (res > 0) @@ -139,7 +143,7 @@ core_check_access(void *data, struct pw_client *client) } if (impl->properties && (str = pw_properties_get(impl->properties, "restricted")) != NULL) { - res = check_cmdline(client, ucred, str); + res = check_cmdline(client, pid, str); if (res == 0) goto granted; if (res < 0) { @@ -153,7 +157,7 @@ core_check_access(void *data, struct pw_client *client) goto wait_permissions; } - res = check_flatpak(client, ucred); + res = check_flatpak(client, pid); if (res != 0) { if (res < 0) { pw_log_warn("module %p: client %p sandbox check failed: %s", diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index e5ed6b62..6e384495 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -251,24 +251,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; + char buffer[1024]; + + props = pw_properties_new(PW_CLIENT_PROP_PROTOCOL, "protocol-native", NULL); + if (props == NULL) + goto exit; len = sizeof(ucred); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) { pw_log_error("no peercred: %m"); - ucredp = NULL; } else { - ucredp = &ucred; + 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); } - props = pw_properties_new(PW_CLIENT_PROP_PROTOCOL, "protocol-native", NULL); - if (props == NULL) - goto exit; + 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/modules/module-protocol-native/test-connection.c b/src/modules/module-protocol-native/test-connection.c index 7113aaf1..eadc9efd 100644 --- a/src/modules/module-protocol-native/test-connection.c +++ b/src/modules/module-protocol-native/test-connection.c @@ -22,6 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ +#include <sys/socket.h> + #include <spa/pod/parser.h> #include <pipewire/pipewire.h> diff --git a/src/pipewire/client.c b/src/pipewire/client.c index 695374dd..dbaa5fbf 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -244,7 +244,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) { @@ -260,20 +259,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); p = pw_array_add(&impl->permissions, sizeof(struct pw_permission)); p->id = SPA_ID_INVALID; @@ -371,15 +362,6 @@ const struct pw_properties *pw_client_get_properties(struct pw_client *client) } 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) { return client->user_data; diff --git a/src/pipewire/client.h b/src/pipewire/client.h index c60498d8..f2e301cd 100644 --- a/src/pipewire/client.h +++ b/src/pipewire/client.h @@ -29,14 +29,6 @@ extern "C" { #endif -#ifdef _GNU_SOURCE -#ifndef __USE_GNU -#define __USE_GNU -#endif -#endif - -#include <sys/socket.h> - #include <spa/utils/hook.h> /** \class pw_client @@ -124,11 +116,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 */); @@ -169,9 +161,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, |