mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-13 13:30:05 -05:00
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)
This commit is contained in:
parent
e0eeedc369
commit
3854f8557a
5 changed files with 49 additions and 52 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,12 +24,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <spa/utils/hook.h>
|
||||
|
||||
/** \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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue