diff --git a/src/modules/flatpak-utils.h b/src/modules/flatpak-utils.h new file mode 100644 index 000000000..331c879b2 --- /dev/null +++ b/src/modules/flatpak-utils.h @@ -0,0 +1,88 @@ +/* PipeWire + * + * Copyright © 2018 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef FLATPAK_UTILS_H +#define FLATPAK_UTILS_H + +#include +#include +#include +#include +#include + +#include +#include + + +static int pw_check_flatpak(pid_t pid) +{ +#if defined(__linux__) + char root_path[2048]; + int root_fd, info_fd, res; + struct stat stat_buf; + + snprintf(root_path, sizeof(root_path), "/proc/%d/root", (int)pid); + root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); + if (root_fd == -1) { + res = -errno; + if (res == -EACCES) { + struct statfs buf; + /* Access to the root dir isn't allowed. This can happen if the root is on a fuse + * filesystem, such as in a toolbox container. We will never have a fuse rootfs + * in the flatpak case, so in that case its safe to ignore this and + * continue to detect other types of apps. */ + if (statfs(root_path, &buf) == 0 && + buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */ + return 0; + } + /* Not able to open the root dir shouldn't happen. Probably the app died and + * we're failing due to /proc/$pid not existing. In that case fail instead + * of treating this as privileged. */ + pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res)); + return res; + } + info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY); + close (root_fd); + if (info_fd == -1) { + if (errno == ENOENT) { + pw_log_debug("no .flatpak-info, client on the host"); + /* No file => on the host */ + return 0; + } + res = -errno; + pw_log_error("error opening .flatpak-info: %m"); + return res; + } + if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) { + /* Some weird fd => failure, assume sandboxed */ + pw_log_error("error fstat .flatpak-info: %m"); + } + close(info_fd); + return 1; +#else + return 0; +#endif +} + +#endif /* FLATPAK_UTILS_H */ diff --git a/src/modules/module-access.c b/src/modules/module-access.c index a5df8aa5e..bc0928943 100644 --- a/src/modules/module-access.c +++ b/src/modules/module-access.c @@ -46,6 +46,8 @@ #include #include +#include "flatpak-utils.h" + /** \page page_module_access PipeWire Module: Access * * @@ -184,54 +186,6 @@ exit: return res; } -#if defined(__linux__) -static int check_flatpak(struct pw_impl_client *client, int pid) -{ - char root_path[2048]; - int root_fd, info_fd, res; - struct stat stat_buf; - - 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) { - res = -errno; - if (res == -EACCES) { - struct statfs buf; - /* Access to the root dir isn't allowed. This can happen if the root is on a fuse - * filesystem, such as in a toolbox container. We will never have a fuse rootfs - * in the flatpak case, so in that case its safe to ignore this and - * continue to detect other types of apps. */ - if (statfs(root_path, &buf) == 0 && - buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */ - return 0; - } - /* Not able to open the root dir shouldn't happen. Probably the app died and - * we're failing due to /proc/$pid not existing. In that case fail instead - * of treating this as privileged. */ - pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res)); - return res; - } - info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY); - close (root_fd); - if (info_fd == -1) { - if (errno == ENOENT) { - pw_log_debug("no .flatpak-info, client on the host"); - /* No file => on the host */ - return 0; - } - res = -errno; - pw_log_error("error opening .flatpak-info: %m"); - return res; - } - if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) { - /* Some weird fd => failure, assume sandboxed */ - pw_log_error("error fstat .flatpak-info: %m"); - } - close(info_fd); - return 1; -} -#endif - static void context_check_access(void *data, struct pw_impl_client *client) { @@ -298,8 +252,7 @@ context_check_access(void *data, struct pw_impl_client *client) (access = pw_properties_get(impl->properties, "access.force")) != NULL) goto wait_permissions; -#if defined(__linux__) - res = check_flatpak(client, pid); + res = pw_check_flatpak(pid); if (res != 0) { if (res < 0) { if (res == -EACCES) { @@ -315,7 +268,7 @@ context_check_access(void *data, struct pw_impl_client *client) access = "flatpak"; goto wait_permissions; } -#endif + if ((access = pw_properties_get(props, PW_KEY_CLIENT_ACCESS)) == NULL) access = "unrestricted"; diff --git a/src/modules/module-protocol-pulse/server.c b/src/modules/module-protocol-pulse/server.c index 0d9e5a990..1a9b3df93 100644 --- a/src/modules/module-protocol-pulse/server.c +++ b/src/modules/module-protocol-pulse/server.c @@ -60,6 +60,7 @@ #include "server.h" #include "stream.h" #include "utils.h" +#include "flatpak-utils.h" #define LISTEN_BACKLOG 32 #define MAX_CLIENTS 64 @@ -423,7 +424,7 @@ on_connect(void *data, int fd, uint32_t mask) pw_log_warn("setsockopt(SO_PRIORITY) failed: %m"); #endif pid = get_client_pid(client, client_fd); - if (pid != 0 && check_flatpak(client, pid) == 1) + if (pid != 0 && pw_check_flatpak(pid) == 1) client_access = "flatpak"; } else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) {